5

I'm a beginner playing with javascript and react. The problem I'm stuck with is that I have an array consisting of strings, and now I want to convert these strings to keys in an object so I can give them a value.

In other words: I have ["panel1", "panel2"] and I want to convert it to {"panel1":false,"panel2":false}.

After hours of searching, I managed to conjure up a working solution:

const names = ["panel1", "panel2"]
var initialState = {};
Object.keys(names).forEach((name) => initialState = { ...initialState,
  [names[name]]: false
})
console.log(JSON.stringify(initialState))

... but looping a function to dynamically expand the object like this seems very unelegant. What would be a better way of doing this? Note that I need my object to be in the same order as the array.

2 Answers 2

7

The problem with yoru code is that the result of Object.keys(names) is the array ["0", "1"] (the keys of the array), not the names.

I'd use a for-of loop:

const initialState = {};
for (const name of names) {
    initialState[name] = false;
}

Or if you can't use ES2015+ features, a for loop:

var initialState = {};
for (var i = 0; i < names.length; ++i) {
    initialState[names[i]] = false;
}

Another approach is to use map to create an array of [name, value] arrays from your names array, then create the object using Object.fromEntries:

const initialState = Object.fromEntries(names.map(name => [name, false]));

map is from ES5, and Object.fromEntriees is quite new but easily polyfilled for older environments.

Sign up to request clarification or add additional context in comments.

2 Comments

Excellent answer. I learnt a lot! First, that you can set object values like "object[key] = value". If only I'd have figured that out sooner. Why I didn't see that during hours of googling will remain a mystery forever. Also, you had me google "ES2015" and "transpilation". Apparently it's a good thing that I came in as late as I did :) Your third example is exactly what I was looking for. Very elegant and readable. I'll use that. But I'm glad that the other examples taught me more about what goes on "below decks". Thanks.
@SadBunny - Glad that helped! FWIW, if you're interested in the new stuff starting from ES2015, my new book is out in a couple of months,... :-) See my profile for links if you're interested. Happy coding!
3

You can use Array.prototype.reduce to do this elegantly:

const names = ["panel1", "panel2"]
initialState = names.reduce((acc, name) => {
  acc[name] = false;
  return acc;
}, {});
console.log(JSON.stringify(initialState))

2 Comments

I'm with Brian Terlson and Jake Archibald: reduce is overcomplicated for things like this where a simple loop is all that's needed, or a call to a more specific method like Object.fromEntries. Nearly every use of reduce really should just be a loop, IMHO.
Your answer works, but to be honest, I don't understand how or why. But it inspires me to look into the reduce thing :) Thanks.

Your Answer

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.