Novice JS developer, need some help in identifying what I am doing wrong.
I have an array of objects
const ll = [{name:"a", ids:[1]}, {name:"b", ids:[2,3]}];
I want to convert it to following
[
{ name: 'a', ids: null, id: 1 },
{ name: 'b', ids: null, id: 2 },
{ name: 'b', ids: null, id: 3 }
]
essentially adding one record for each element in ids
array.
This is the code I wrote
ll.reduce((r,o) =>
r.concat(o.ids.map(i => {
const r1 = o;
r1.id = i;
r1.ids = null;
return r1;})),[])
What I am getting is
[
{ name: 'a', ids: null, id: 1 },
{ name: 'b', ids: null, id: 3 },
{ name: 'b', ids: null, id: 3 }
]
why 2 is missing & 3 is repeated?
Thanks in advance for your help on this.
3
Answers
With
const r1 = o
, you are creating a reference to the original objecto
. Hence, when you modifyr1.id
andr1.ids
, it affects all occurrences ofr1
in the resulting array.Create a new object in each iteration and assign the properties individually. Also, you can optimized your code in the following way:
It seems to me the line
const r1 = o;
is causing the problem. The code assigns a reference to the variableo
tor1
, so when you modifyr1
, the original objecto
also change. Because the map function executes for each element ino.ids
, the modifications tor1
affect the final result.To fix this issue, I believe you need to create a new object for each iteration of the map function. I guess you can just use the spread syntax (…) to create a shallow copy of the object. Below is a modification I did to your original code:
Here’s a solution using
Array#flatMap()
:(A terser version can be found in the snippet below.)
Try it: