javascript - Jämför 2 arrayer med objekt efter 2 olika nycklar. Och skapa ett inbäddat objekt som innehåller förälder och barn
Jag har problem med att jämföra 2 arrayer av objekt. Jag sökte i lodash-dokumentationen, men jag kunde inte hitta någon lämplig metod. Saken är den att jag behöver jämföra objekt med olika nycklar.
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' }
];
Jag behöver skapa en ny array av nästlade objekt där 'parentId' kommer att matchas med 'Id' för föräldern vilket kommer att se ut så här:
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' }
]
}
];
Jag använde '.intersectionWith([arrays], [comparator])' och '.isMatchWith(object, source, [customizer])' men det gav mig inte vad jag behöver. Jag skulle vara tacksam för all hjälp.
Svar #1
Det enklaste sättet att göra detta är förmodligen
const newArray = parentArray.map(
p => ({ ...p, Children: childArray.filter(c => c.parentId === p.Id) })
)
vilket resulterar i den utgång du letar efter. Observera att detta inte nödvändigtvis är den mest effektiva algoritmen i fallet där parentArray och childArray är stora, eftersom vi loopar över hela childArray för varje element i parentArray (så om childArray är av längden 𝑐 ochit är överordnad av Array och är O(𝑝×𝑐)).
Om sådan prestanda är viktig kan du göra det genom att iterera över varje element i childArray och parentArray en gång (vilket är O(𝑝+𝑐) förutsatt att hash-uppslagningar är O(1)), på detta sätt:
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);
Lekplatslänk till kod
Svar #2
type Parent = {
Id: number,
Name: string,
}
type Child = Parent & {
parentId: number;
}
type ParentAndChildren = {
Children: Child[]
} & Parent
const parents: Parent[] = [
{ Id: 1, Name: 'A' },
{ Id: 2, Name: 'B' },
{ Id: 3, Name: 'C' },
{ Id: 4, Name: 'D' }
];
const children: Child[] = [
{ Id: 2, parentId: 2, Name: 'a' },
{ Id: 3, parentId: 2, Name: 'b' },
{ Id: 4, parentId: 4, Name: 'c' },
{ Id: 5, parentId: 4, Name: 'd' }
];
const output = parents.map((p: Parent): ParentAndChildren => {
return {
Id: p.Id,
Name: p.Name,
Children: children.filter((c) => p.Id === c.parentId),
}
})
console.log(output);
