DEV Community
Originally posted on afewminutesofcode.com
To convert an array into an object we will create a function and give it 2 properties, an array and a key.
const convertArrayToObject = (array, key) => {};
We will then reduce the array, and create a unique property for each item based on the key we have passed in.
We also need to remember to set an initial Value, and also pass in the current value (...obj in the below).
const convertArrayToObject = (array, key) => {
const initialValue = {};
return array.reduce((obj, item) => {
return {
...obj,
[item[key]]: item,
};
}, initialValue);
};
So now if we log out our function (passing in the array and our key which is a unique identifier in this case the id property) we will see our array is now an object.
console.log(
convertArrayToObject(
[
{ id: 111, name: 'John', age: 29 },
{ id: 112, name: 'Sarah', age: 25 },
{ id: 122, name: 'Kate', age: 22 },
{ id: 123, name: 'Tom', age: 21 },
{ id: 125, name: 'Emma', age: 24 },
],
'id',
),
);
returns
{
111:{ id: 111, name: 'John', age: 29 },
112:{ id: 112, name: 'Sarah', age: 25 },
122:{ id: 122, name: 'Kate', age: 22 },
123:{ id: 123, name: 'Tom', age: 21 },
125:{ id: 125, name: 'Emma', age: 24 }
}
We can now easily look up data in our array by an id and use it as required.
If you are looking for some more tips or want to be notified when my next post is available follow Me Online Here:
Instagram
Facebook
afewminutesofcode.com
Twitter
Pinterest
I faced out with this problem and I took as a reference: stackoverflow.com/a/44325124
And I created some similar that your solution but with less lines and more faster
const convertArrayToObject = (array, key) =>
array.reduce((obj, item) => ((obj[[item[key]]] = item), obj), {});
I have another example to wotk with your Code, but I didn't reach it.
My Array:
[
{"name":"Product 1","series":{"name":"Area 1","value":3}},
{"name":"Product 2","series":{"name":"Area 2","value":3}},
{"name":"Product 1","series":{"name":"Area 2","value":1}},
]
Need to convert it to an object like this:
[ {"name": "Product 1",
"series":[{"name":"Area 1","value":3},{"name":"Area 2","value":1}] },
{"name":"Product 2",
"series":[{"name":"Area 2","value":3}] }
];
It would be nice if you could give my any advice how to reach this by adopting your Code?
I would do something like this below to get the result (not nice or fast but should do the job :D):
const arr = [
{"name":"Product 1","series":{"name":"Area 1","value":3}},
{"name":"Product 2","series":{"name":"Area 2","value":3}},
{"name":"Product 1","series":{"name":"Area 2","value":1}},
];
const result = [... new Set(arr.map(x=>x.name))].map(x=>({"name":x,"series":[]}));
arr.forEach(x=>result.find(y=>y.name===x.name).series.push(x.series));
JSON.stringify(result,null,3);
It cannot work without it, it makes no sense. I've just generated array with unique names and empty series array at first (result), this one is pushing all the series objects data into these empty series arrays in result array.
It's just going through original array (arr) to pick series object and push it in result series array - names properties has to match hence y.name===x.name
Top comments (33)
This is good, anyhow is an antipattern, it should be something like:
In this way, you avoid the spread op which is a way expensive than a single assignment
Hey, man, I like code golfing too, but just because something can be written more concisely, it doesn't mean we should. Your second solution is kinda difficult to read because it's so cluttered and it also obligates people to know what the comma operator is and how it works. I just don't see how this is better than your first solution once the bundler will already minify the code for us, we don't need to write and read minified code, just be aware everyone, if you're gonna copy this, copy the first one, the people reading your code in the future will be happier :D
I was a bit surprised by your claim regarding the spread operator being anti-pattern so I asked around and it seems that there are different opinions regarding that. Would you care to throw in some info to shed more light on the topic?
Thanks for taking the time to help me and others out here! I am going to read up on the Comma operator in JavaScript developer.mozilla.org/en-US/docs/W... do you have any other resources you recomend here?
There is no comma operator here
yes, there is, it's right above the line of the "Basically everything..."
there is no item var around it should be curr did you even write that code alone?
Nice!
I had to write one of these the other day.
Here's a slightly more concise version, where you throw out extra brackets and use an implicit return 😄 :
the
[item[key]]
tripped me up initially haha.Thanks so much for pointing this out Brad! I have used this syntax for one liner map functions but had overlooked using it with reduce before. I am going to make sure I use it in the future, to keep my code more concise.
Thanks man💪
So long as you don't have to support older browsers, or are using Babel, new ES features do this without the need of a helper function. See the MDN docs for Object.fromEntires.
Thanks Paul, I have done some reading on this feature a few months back but hadn't seen how I could apply this to my problem.
There is another comment from ygorbunkov which demonstrates how to do this so I will have a reference point if I need to use something similar again soon!