4
\$\begingroup\$

I'm trying to create a filtered list of objects where each object in the list has both a label and value property.

First I use .pick to select the key/value pairs I want from the initial object, then I iterate over the 'picked' properties and push the key into an object property called label, and push the value of the property into a property called value. I then return the empty array.

function formatToInput(obj, list) {
    var empty = []

    _.forIn(_.pick(obj, list), (val, key) => {
        empty.push({
            label: _.startCase(key),
            value: val
        });
    });

    return empty;
}

// use like so

var test = {blue: 10, green: 5, yellow: 3, pink: 1};
var filter = ['green', 'yellow'];

var results = formatToInput(test, filter)

console.log(results);

// [{label: Green, value: 5}, {label: Yellow, value: 3}]

I'm trying to avoid having to manually create an array and pushing objects into it, but I couldn't find a solution (in Lodash) that would allow me to do this.

\$\endgroup\$
  • \$\begingroup\$ Is there any chance to have values in filter which are not in test? \$\endgroup\$ – Tushar Jun 21 '17 at 4:55
3
\$\begingroup\$

The code looks like you're passing the processed data to autocomplete.

Naming

  • formatToInput: This gives no idea of what the function is doing.
  • empty: Is it really empty at the end of formatToInput?
  • obj, list: Confusing.
  • test, results: Can be named better.

Lodash

Do you really need a library for this functionality? The Same functionality can be done without Lodash or any other library. If Lodash is only used for this functionality, it can be removed.

Missing Semi-colons

Although, a small thing Automatic Semicolon Insertion can lead to unexpected behavior. The usage of the semi-colon is not consistent. I'll recommend using JSLint/JSHint.

Alternative

I'll recommend the use of Array#map and String methods to make the first character uppercase.

const colorValueMap = {
  blue: 10,
  green: 5,
  yellow: 3,
  pink: 1
};
const colors = ['green', 'yellow'];

const result = colors.map(color => ({
  label: color[0].toUpperCase() + color.slice(1),
  value: colorValueMap[color]
}));
console.log(result);


Above solution assumes that the value from the filter array always exists in the object. If this is not the case, you can first filter the array and then use map on it.

colors.filter(color => colorValueMap.hasOwnProperty(color)).map(color => ({
    ...
});
\$\endgroup\$
  • \$\begingroup\$ Functionally this is a bit different, the original only copies over existing attributes from the filter. You create all attributes regardless, with undefined values when the original object does not have the attribute. Perhaps you could first filter, then map? \$\endgroup\$ – konijn Jun 20 '17 at 20:57
  • \$\begingroup\$ @konijn True. I've updated the answer. Thanks :) \$\endgroup\$ – Tushar Jun 21 '17 at 7:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.