Issue
I have problem with comparing 2 arrays of objects. I was searching lodash documentation, but I was not able to find proper method. The thing is that I need to compare objects by different keys.
private parentArray: {}[] = [
{ Id: 1, Name: 'A' },
{ Id: 2, Name: 'B' },
{ Id: 3, Name: 'C' },
{ Id: 4, Name: 'D' }
];
private childArray: {}[] = [
{ Id: 2, parentId: 2, Name: 'a' },
{ Id: 3, parentId: 2, Name: 'b' },
{ Id: 4, parentId: 4, Name: 'c' },
{ Id: 5, parentId: 4, Name: 'd' }
];
I need to make a new array of nested objects where 'parentId' will be matched with 'Id' of parent which will look like that:
private newArray = [
{ Id: 1, Name: 'A', Children: [] },
{
Id: 2,
Name: 'B',
Children: [
{ Id: 2, parentId: 2, Name: 'a' },
{ Id: 3, parentId: 2, Name: 'b' }
]
},
{
Id: 3,
Name: 'C',
Children: []
},
{
Id: 4,
Name: 'D',
Children: [
{ Id: 4, parentId: 4, Name: 'c' },
{ Id: 5, parentId: 4, Name: 'd' }
]
}
];
I was using '.intersectionWith([arrays], [comparator])' and '.isMatchWith(object, source, [customizer])' but it did not give me what I need. I will be grateful for any help.
Solution
The simplest way to do this is probably
const newArray = parentArray.map(
p => ({ ...p, Children: childArray.filter(c => c.parentId === p.Id) })
)
which results in the output you are looking for. Note that this is not necessarily the best performing algorithm in the case where parentArray and childArray are large, since we are looping over the entire childArray for every element in parentArray (so if childArray is length 𝑐 and parentArray is length 𝑝 then this algorithm is O(𝑝×𝑐)).
If such performance matters then you can do it by iterating over each element in childArray and parentArray once (which is O(𝑝+𝑐) assuming hash lookups are O(1)), like this:
type Parent = typeof parentArray[number];
type Child = typeof childArray[number];
interface New extends Parent {
Children: Child[];
}
const newArray: New[] = [];
const parentLookup: Record<number, New> = {};
for (const p of parentArray) {
const n = { ...p, Children: [] };
newArray.push(n)
parentLookup[p.Id] = n;
}
for (const c of childArray) {
parentLookup[c.parentId]?.Children.push(c);
}
console.log(newArray);
Answered By - jcalz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.