Reputation: 1583
I am a JavaScript beginner. I want to merge a nested array with "id" <-- unique for all the array of objects. The A and B keys are dynamic (ex. A, B, C, D, and so on) and can be added later. Whereas the dummy key is of a kind where if the dummy value of all the 3 arrays matches then only it will show in the final result; else it will show as - (hyphen)
let arr1 = [
{
A: 0.71,
B: 0.52,
id: 1,
dummy: 1,
},
{
A: 0.72,
B: 0.50,
id: 2,
dummy: 1,
},
];
let arr2 = [
{
A: 0.157,
B: 0.02255,
id: 1,
dummy: 1,
},
{
A: 0.16761,
B: 0.028281,
id: 2,
dummy: 1,
},
];
let arr3 = [
{
A: 0.55,
B: 0.50,
id: 1,
dummy: 1,
},
{
A: 0.5,
B: 0.43,
id: 2,
dummy: 1,
},
];
I want these in one array as finalArray with contains id and all the three arrays inside those with their respective ids
let finalArr = [
{
id: 1,
dummy: 1,
arr1_A: 0.71,
arr1_B: 0.52,
arr2_A: 0.157,
arr2_B: 0.02255,
arr3_A: 0.55,
arr3_B: 0.5,
},
{
id: 2,
dummy: 1,
arr1_A: 0.72,
arr1_B: 0.5,
arr2_A: 0.16761,
arr2_B: 0.028281,
arr3_A: 0.5,
arr3_B: 0.43,
},
];
Upvotes: 0
Views: 119
Reputation: 7616
You can first gather the data by id using a .reduce()
, then transform the data into your desired array format:
UPDATE 2022-12-09: C\I changed below code based on changed requirements by OP:
"arr1": { "A": 0.71, "B": 0.52 },
to a flat "arr1_A": 0.71, "arr1_B": 0.52,
let arr1 = [
{ A: 0.71, B: 0.52, id: 1, dummy: 1, },
{ A: 0.72, B: 0.50, id: 2, dummy: 1, },
];
let arr2 = [
{ A: 0.157, B: 0.02255, id: 1, dummy: 1, },
{ A: 0.16761, B: 0.028281, id: 2, dummy: 1, },
];
let arr3 = [
{ A: 0.55, B: 0.50, id: 1, dummy: 1, },
{ A: 0.5, B: 0.43, id: 2, dummy: 99, },
];
let idMap = arr1.concat(arr2).concat(arr3).reduce((acc, obj) => {
if(!acc[obj.id]) {
acc[obj.id] = {
dummy: obj.dummy,
arrs: []
}
}
if(obj.dummy != acc[obj.id].dummy) {
acc[obj.id].dummy = '-';
}
acc[obj.id].arrs.push({ A: obj.A, B: obj.B });
return acc;
}, {});
let finalArr = Object.keys(idMap).map(id => {
let obj = {
id: id,
dummy: idMap[id].dummy
};
let idx = 1;
idMap[id].arrs.forEach(o => {
Object.keys(o).map(p => {
obj['arr' + idx + '_' + p] = o[p];
});
idx++;
});
return obj;
});
console.log(finalArr);
Upvotes: 2
Reputation: 30675
You can use Array.reduce()
to group the items by id
.
First we'd gather up each array into an inputs
object, combining the name and value of each array.
We can use Object.entries()
along with .reduce() to iterate over our inputs.
A mapping object will be created with one entry for each id
and a dummy value corresponding to the initial value for that id. If the dummy value for an id changes, we flag it with '-'.
We add a property to each value at id
with the naming convention ${arr}_${prop}
for each property in each iterated object.
We can finally use Object.values()
to get the result as an array rather than an object.
const arr1 = [ { A: 0.71, B: 0.52, id: 1, dummy: 1, }, { A: 0.72, B: 0.50, id: 2, dummy: 1, }, ];
const arr2 = [ { A: 0.157, B: 0.02255, id: 1, dummy: 1, }, { A: 0.16761, B: 0.028281, id: 2, dummy: 1, }, ];
const arr3 = [ { A: 0.55, B: 0.50, id: 1, dummy: 1, }, { A: 0.5, B: 0.43, id: 2, dummy: 1, }, ];
const inputs = { arr1, arr2, arr3 };
const result = Object.values(Object.entries(inputs).reduce((acc, [key, arr]) => {
return arr.reduce((acc, { id, dummy, ...obj}) => {
acc[id] = acc[id] || { id, dummy };
for(let prop in obj) {
acc[id][`${key}_${prop}`] = obj[prop];
}
if (dummy !== acc[id].dummy) {
acc[id].dummy = '-';
}
return acc;
}, acc);
}, {}))
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
Upvotes: 1
Reputation: 128
The same solution without map and reduce methods for old browsers as well
let arr1 = [
{ A: 0.71, B: 0.52, id: 1, dummy: 1, },
{ A: 0.72, B: 0.50, id: 2, dummy: 1, },
];
let arr2 = [
{ A: 0.157, B: 0.02255, id: 1, dummy: 1, },
{ A: 0.16761, B: 0.028281, id: 2, dummy: 1, },
];
let arr3 = [
{ A: 0.55, B: 0.50, id: 1, dummy: 1, },
{ A: 0.5, B: 0.43, id: 2, dummy: 1, },
];
let finalArr = []
let keysToUse = ['id', 'dummy'];
let countOfIds = arr1.length;
let ids = arr1.map(d => d.id);
let varArrayToUse = ['arr1', 'arr2', 'arr3'];
// console.log('len '+countOfIds)
for(var i = 0; i < ids.length; i++){
finalArr[i] = {
id: arr1[i].id,
dummy: arr1[i].dummy,
}
for(var j = 0; j < varArrayToUse.length; j++) {
if (j == 0) { targetArr = arr1 } else if (j == 1) {targetArr = arr2} else {targetArr = arr3}
finalArr[i][varArrayToUse[j]] =
{
A: (targetArr[i]).A,
B: (targetArr[i]).B
}
}
}
console.log(finalArr)
Upvotes: 1