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.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jun 20, 2017 at 2:50
\$\endgroup\$
1
  • \$\begingroup\$ Is there any chance to have values in filter which are not in test? \$\endgroup\$ Commented Jun 21, 2017 at 4:55

1 Answer 1

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 => ({
 ...
});
answered Jun 20, 2017 at 6:23
\$\endgroup\$
2
  • \$\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\$ Commented Jun 20, 2017 at 20:57
  • \$\begingroup\$ @konijn True. I've updated the answer. Thanks :) \$\endgroup\$ Commented Jun 21, 2017 at 7:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.