Reputation: 15599
I have 3 JSON objects as defined below:
const totalData = [{ Hostname: "abc123", name: "CName-A", Status: "PASS", Heading: "Not Applicable" },
{ Hostname: "abc123", name: "CName-B", Status: "FAIL", Heading: "Not Applicable" },
{ Hostname: "abc235", name: "CName-C", Status: "FAIL", Heading: "Not Applicable" },
{ Hostname: "abc235", name: "CName-D", Status: "FAIL", Heading: "Not Applicable" }];
const otherTotalData = [{ Hostname: "abc123", name: "QName-A", Status: "PASS", Heading: "HeadingQA" },
{ Hostname: "abc123", name: "QName-B", Status: "FAIL", Heading: "HeadingQB" },
{ Hostname: "abc235", name: "QName-C", Status: "FAIL", Heading: "Not Applicable" },
{ Hostname: "abc235", name: "QName-D", Status: "FAIL", Heading: "Not Applicable" }];
const newTotalData = [{ Hostname: "abc123", name: "TName-A", Status: "PASS", Heading: "HeadingTA" },
{ Hostname: "abc123", name: "TName-B", Status: "FAIL", Heading: "HeadingTB" },
{ Hostname: "abc235", name: "TName-C", Status: "FAIL", Heading: "Not Applicable" },
{ Hostname: "abc235", name: "TName-D", Status: "FAIL", Heading: "Not Applicable" }];
I have a function which uses array reduce
method:
function createArray(totalData) {
const keyValues = ["Status", "Heading"],
result = Object.values(totalData.reduce((res, { Hostname, name, ...o }) => {
res[Hostname] = res[Hostname] || { Hostname };
keyValues.forEach(k => res[Hostname][name + k] = o[k]);
return res;
}, {}));
}
Now, I am calling the two functions:
const Res1 = createArray(totalData);
const Res2 = createArray(otherTotalData);
const Res3 = createArray(newTotalData);
Here Res1 has the output:
[
{
"Hostname": "abc123",
"CName-AStatus": "PASS",
"CName-BStatus": "FAIL"
},
{
"Hostname": "abc235",
"CName-CStatus": "FAIL",
"CName-DStatus": "FAIL"
}
]
And, Res2 has the output:
[
{
"Hostname": "abc123",
"QName-AStatus": "PASS",
"QName-BStatus": "FAIL"
},
{
"Hostname": "abc235",
"QName-CStatus": "FAIL",
"QName-DStatus": "FAIL"
}
]
And, Res3 has the output:
[
{
"Hostname": "abc123",
"TName-AStatus": "PASS",
"TName-BStatus": "FAIL"
},
{
"Hostname": "abc235",
"TName-CStatus": "FAIL",
"TName-DStatus": "FAIL"
}
]
I want to combine Res1, Res2 and Res3 such that the final Json object looks as following:
[
{
"Hostname": "abc123",
"CName-AStatus": "PASS",
"CName-BStatus": "FAIL",
"QName-AStatus": "PASS",
"QName-BStatus": "FAIL",
"TName-AStatus": "PASS",
"TName-BStatus": "FAIL"
},
{
"Hostname": "abc235",
"CName-CStatus": "FAIL",
"CName-DStatus": "FAIL",
"QName-CStatus": "FAIL",
"QName-DStatus": "FAIL",
"TName-CStatus": "FAIL",
"TName-DStatus": "FAIL"
}
]
How can I combine Res1
Res2
and Res3
?
Upvotes: 0
Views: 59
Reputation: 10790
Basically you can search the other array with shared property: "Hostname" and use Object.assign
to combine two objects together.
const res1 = [{
"Hostname": "abc123",
"CName-AStatus": "PASS",
"CName-BStatus": "FAIL"
},
{
"Hostname": "abc235",
"CName-CStatus": "FAIL",
"CName-DStatus": "FAIL"
}
];
const res2 = [{
"Hostname": "abc123",
"QName-AStatus": "PASS",
"QName-BStatus": "FAIL"
},
{
"Hostname": "abc235",
"QName-CStatus": "FAIL",
"QName-DStatus": "FAIL"
}
];
const res3 = [{
"Hostname": "abc123",
"TName-AStatus": "PASS",
"TName-BStatus": "FAIL"
},
{
"Hostname": "abc235",
"TName-CStatus": "FAIL",
"TName-DStatus": "FAIL"
}
];
function mergeAll(key, ...args) {
const arr = Array.from(args);
const first = arr[0];
const rest = arr.slice(1);
return first.map(r => Object.assign({}, r, ...rest.map(q => q.find(t => t[key] === r[key]))));
}
const result = mergeAll('Hostname', res1, res2, res3);
console.log(result);
Edit: As Op mentioned in the comments there are 3 results to merge so I made a generalized method for any number of results.
Upvotes: 1
Reputation: 37755
You can just map over one array and use index to get respective value from another array and merge values
let res1 = [{"Hostname": "abc123","CName-AStatus": "PASS","CName-BStatus": "FAIL"},{"Hostname": "abc235","CName-CStatus": "FAIL","CName-DStatus": "FAIL"}]
let res2 = [{"Hostname": "abc123","QName-AStatus": "PASS","QName-BStatus": "FAIL"},{"Hostname": "abc235","QName-CStatus": "FAIL","QName-DStatus": "FAIL"}]
let final = res1.map((inp, index) => {
return { ...inp,
...res2[index]
}
})
console.log(final)
P.S:- This considers the arrays are sorted in same order and always a respective value is present in other array. ( considering your given example data ). If that is not the case then we just need to find the respective value from other array based on some property and the merge.
let res1 = [{"Hostname": "abc123","CName-AStatus": "PASS","CName-BStatus": "FAIL"},{"Hostname": "abc235","CName-CStatus": "FAIL","CName-DStatus": "FAIL"}]
let res2 = [{"Hostname": "abc235","QName-CStatus": "FAIL","QName-DStatus": "FAIL"},{"Hostname": "abc123","QName-AStatus": "PASS","QName-BStatus": "FAIL"}]
let final = [...res1,...res2].reduce((op,inp)=>{
let key = inp.Hostname
if(op.has(key)){
op.set(key, {...op.get(key), ...inp} )
} else{
op.set(key, inp)
}
return op
}, new Map())
console.log([...final.values()])
Upvotes: 1