Having the two JSON arrays, I'd like to merge them in one finall JSON array. The base array is the following having sublevels:
r1=[{
"item_guid": "5c2000c1-abc8-4d6f-85de-b8b223a42a2f",
"item_id": 1,
"parent_item_id": null,
"description": "1",
"sub_items": [
{
"item_guid": "bd7c2ba3-268b-49f6-98fb-34486a3e1449",
"item_id": 10,
"parent_item_id": 1,
"description": "1.1",
"sub_items": []
},
{
"item_guid": "80e073e0-2aa8-422a-9f28-51747f146bd8",
"item_id": 12,
"parent_item_id": 1,
"description": "1.2",
"sub_items": [
{
"item_guid": "f97af55c-c90e-46c2-b56e-e854ff36e1e3",
"item_id": 78,
"parent_item_id": 12,
"description": "1.2.1",
"sub_items": []
},
{
"item_guid": "28469fa4-2c1c-4f2a-9250-7460a74cc30a",
"item_id": 79,
"parent_item_id": 12,
"description": "1.2.2",
"sub_items": [
{
"item_guid": "f97af55c-c90e-46c2-b56e-e854ff36e1e9",
"item_id": 80,
"parent_item_id": 12,
"description": "1.2.2.1",
"sub_items": []
},
]
}
],
},
{
"item_guid": "846daeab-edd4-4cf2-8f12-8d7231c697e3",
"item_id": 13,
"parent_item_id": 1,
"description": "1.3",
"sub_items": [],
},
],
}]
The second array is used to copy its items to the matching element in the first array:
r2=[
{
"item_guid": "bd7c2ba3-268b-49f6-98fb-34486a3e1449",
"mandatory": "True",
"comment": "Item cross-reference 1.1"
},
{
"item_guid": "f97af55c-c90e-46c2-b56e-e854ff36e1e3",
"mandatory": "True",
"comment": "Item cross-reference 1.2.1"
},
{
"item_guid": "f97af55c-c90e-46c2-b56e-e854ff36e1e9",
"mandatory": "True",
"comment": "Item cross-reference 1.2.2.1"
}]
The result should be the following:
r3=[{
"item_guid": "5c2000c1-abc8-4d6f-85de-b8b223a42a2f",
"item_id": 1,
"parent_item_id": null,
"description": "1",
"sub_items": [
{
"item_guid": "bd7c2ba3-268b-49f6-98fb-34486a3e1449",
"item_id": 10,
"parent_item_id": 1,
"description": "1.1",
"mandatory": "True",
"comment": "Item cross-reference 1.1"
"sub_items": []
},
{
"item_guid": "80e073e0-2aa8-422a-9f28-51747f146bd8",
"item_id": 12,
"parent_item_id": 1,
"description": "1.2",
"sub_items": [
{
"item_guid": "f97af55c-c90e-46c2-b56e-e854ff36e1e3",
"item_id": 78,
"parent_item_id": 12,
"description": "1.2.1",
"mandatory": "True",
"comment": "Item cross-reference 1.2.1"
"sub_items": []
},
{
"item_guid": "28469fa4-2c1c-4f2a-9250-7460a74cc30a",
"item_id": 79,
"parent_item_id": 12,
"description": "1.2.2",
"sub_items": [
{
"item_guid": "f97af55c-c90e-46c2-b56e-e854ff36e1e9",
"item_id": 80,
"parent_item_id": 12,
"description": "1.2.2.1",
"mandatory": "True",
"comment": "Item cross-reference 1.2.2.1"
"sub_items": []
},
]
}
],
},
{
"item_guid": "846daeab-edd4-4cf2-8f12-8d7231c697e3",
"item_id": 13,
"parent_item_id": 1,
"description": "1.3",
"sub_items": [],
},
],
}]
I have attempted to iterate the first array to match elements in the second array as follows, but I think it would need some recursion to keep checking sub-levels. Could I do using map?
const mergeById = (r1, r2) =>
r1.map(itm => {
itm.sub_items = itm.sub_items.map(sub_item => (
{ ...sub_item,
...r2.find(r2_item => r2_item.item_guid === sub_item.item_guid),
}
)
)
return itm
})
console.log(mergeById(r1,r2))
CodePudding user response:
I would say your .map()
attempt is going into the right direction, and also your hunch that you need recursion. What works is
function mergeById(r1, r2) {
return r1.map(({item_guid, sub_items, ...rest}) => Object.assign(
rest,
{item_guid},
r2.find(_ => _.item_guid === item_guid),
{sub_items: mergeById(sub_items, r2)}
));
}
const r1 = [{item_guid: "5c2000c1-abc8-4d6f-85de-b8b223a42a2f", item_id: 1, parent_item_id: null, description: "1", sub_items: [{item_guid: "bd7c2ba3-268b-49f6-98fb-34486a3e1449", item_id: 10, parent_item_id: 1, description: "1.1", sub_items: []}, {item_guid: "80e073e0-2aa8-422a-9f28-51747f146bd8", item_id: 12, parent_item_id: 1, description: "1.2", sub_items: [{item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e3", item_id: 78, parent_item_id: 12, description: "1.2.1", sub_items: []}, {item_guid: "28469fa4-2c1c-4f2a-9250-7460a74cc30a", item_id: 79, parent_item_id: 12, description: "1.2.2", sub_items: [{item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e9", item_id: 80, parent_item_id: 12, description: "1.2.2.1", sub_items: []}]}]}, {item_guid: "846daeab-edd4-4cf2-8f12-8d7231c697e3", item_id: 13, parent_item_id: 1, description: "1.3", sub_items: []}]}]
const r2 = [{item_guid: "bd7c2ba3-268b-49f6-98fb-34486a3e1449", mandatory: "True", comment: "Item cross-reference 1.1"}, {item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e3", mandatory: "True", comment: "Item cross-reference 1.2.1"}, {item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e9", mandatory: "True", comment: "Item cross-reference 1.2.2.1"}]
console.log(mergeById(r1, r2))
.as-console-wrapper {max-height: 100% !important; top: 0}
Edit 1: add item_guid
as pointed out by @Xupitan
Edit 2: use rest
as throw-away object as suggested by @Scott Sauyet
CodePudding user response:
This is chiefly a variant of the excellent answer from Dominik Schreiber. It's the same technique, only with different coding style, using an object spread instead of Object .assign
.
const deepMerge = (r1, r2) =>
r1 .map (({item_guid, sub_items, ...rest}) => ({
item_guid,
... rest,
... (r2 .find ((i) => i .item_guid == item_guid)),
sub_items: deepMerge (sub_items, r2)
}))
const r1 = [{item_guid: "5c2000c1-abc8-4d6f-85de-b8b223a42a2f", item_id: 1, parent_item_id: null, description: "1", sub_items: [{item_guid: "bd7c2ba3-268b-49f6-98fb-34486a3e1449", item_id: 10, parent_item_id: 1, description: "1.1", sub_items: []}, {item_guid: "80e073e0-2aa8-422a-9f28-51747f146bd8", item_id: 12, parent_item_id: 1, description: "1.2", sub_items: [{item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e3", item_id: 78, parent_item_id: 12, description: "1.2.1", sub_items: []}, {item_guid: "28469fa4-2c1c-4f2a-9250-7460a74cc30a", item_id: 79, parent_item_id: 12, description: "1.2.2", sub_items: [{item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e9", item_id: 80, parent_item_id: 12, description: "1.2.2.1", sub_items: []}]}]}, {item_guid: "846daeab-edd4-4cf2-8f12-8d7231c697e3", item_id: 13, parent_item_id: 1, description: "1.3", sub_items: []}]}]
const r2 = [{item_guid: "bd7c2ba3-268b-49f6-98fb-34486a3e1449", mandatory: "True", comment: "Item cross-reference 1.1"}, {item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e3", mandatory: "True", comment: "Item cross-reference 1.2.1"}, {item_guid: "f97af55c-c90e-46c2-b56e-e854ff36e1e9", mandatory: "True", comment: "Item cross-reference 1.2.2.1"}]
console .log (deepMerge (r1, r2))
.as-console-wrapper {max-height: 100% !important; top: 0}