Here is one option:-
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: ["val2", "val3"]
}, {
name: "foo2",
value: "val4"
}];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name == item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].value = output[existingIndex].value.concat(item.value);
} else {
if (typeof item.value == 'string')
item.value = [item.value];
output.push(item);
}
});
console.dir(output);
Answer from BenG on Stack OverflowHere is one option:-
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: ["val2", "val3"]
}, {
name: "foo2",
value: "val4"
}];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name == item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].value = output[existingIndex].value.concat(item.value);
} else {
if (typeof item.value == 'string')
item.value = [item.value];
output.push(item);
}
});
console.dir(output);
Here is another way of achieving that goal:
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: [
"val2",
"val3"
]
}, {
name: "foo2",
value: "val4"
}];
var output = array.reduce(function(o, cur) {
// Get the index of the key-value pair.
var occurs = o.reduce(function(n, item, i) {
return (item.name === cur.name) ? i : n;
}, -1);
// If the name is found,
if (occurs >= 0) {
// append the current value to its list of values.
o[occurs].value = o[occurs].value.concat(cur.value);
// Otherwise,
} else {
// add the current item to o (but make sure the value is an array).
var obj = {
name: cur.name,
value: [cur.value]
};
o = o.concat([obj]);
}
return o;
}, []);
console.log(output);
javascript - Merge two array of objects based on a key - Stack Overflow
JavaScript merge array objects with the same keys - Stack Overflow
javascript - how to merge objects in array with same key? - Stack Overflow
javascript - Merging objects from array with the same key value - Stack Overflow
You can do it like this -
let arr1 = [
{ id: "abdc4051", date: "2017-01-24" },
{ id: "abdc4052", date: "2017-01-22" }
];
let arr2 = [
{ id: "abdc4051", name: "ab" },
{ id: "abdc4052", name: "abc" }
];
let arr3 = arr1.map((item, i) => Object.assign({}, item, arr2[i]));
console.log(arr3);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Use below code if arr1 and arr2 are in a different order:
let arr1 = [
{ id: "abdc4051", date: "2017-01-24" },
{ id: "abdc4052", date: "2017-01-22" }
];
let arr2 = [
{ id: "abdc4051", name: "ab" },
{ id: "abdc4052", name: "abc" }
];
let merged = [];
for(let i=0; i<arr1.length; i++) {
merged.push({
...arr1[i],
...(arr2.find((itmInner) => itmInner.id === arr1[i].id))}
);
}
console.log(merged);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Use this if arr1 and arr2 are in a same order
let arr1 = [
{ id: "abdc4051", date: "2017-01-24" },
{ id: "abdc4052", date: "2017-01-22" }
];
let arr2 = [
{ id: "abdc4051", name: "ab" },
{ id: "abdc4052", name: "abc" }
];
let merged = [];
for(let i=0; i<arr1.length; i++) {
merged.push({
...arr1[i],
...arr2[i]
});
}
console.log(merged);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
This solution is applicable even when the merged arrays have different sizes. Also, even if the matching keys have different names.
Merge the two arrays by using a Map as follows:
const arr1 = [
{ id: "abdc4051", date: "2017-01-24" },
{ id: "abdc4052", date: "2017-01-22" },
{ id: "abdc4053", date: "2017-01-22" }
];
const arr2 = [
{ nameId: "abdc4051", name: "ab" },
{ nameId: "abdc4052", name: "abc" }
];
const map = new Map();
arr1.forEach(item => map.set(item.id, item));
arr2.forEach(item => map.set(item.nameId, {...map.get(item.nameId), ...item}));
const mergedArr = Array.from(map.values());
console.log(JSON.stringify(mergedArr));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Run the stack snippet to see the result:
[
{
"id": "abdc4051",
"date": "2017-01-24",
"nameId": "abdc4051",
"name": "ab"
},
{
"id": "abdc4052",
"date": "2017-01-22",
"nameId": "abdc4052",
"name": "abc"
},
{
"id": "abdc4053",
"date": "2017-01-22"
}
]
var jsonData = [{
Question: "Was the training useful?",
QuestionId: 1,
myData: [{
name: 'No',
value: 1
}]
},
{
Question: "Was the training useful?",
QuestionId: 1,
myData: [{
name: 'Yes',
value: 1
}]
}
];
const result = Object.values(jsonData.reduce((acc, obj) => {
if (!acc[obj.QuestionId]) {
acc[obj.QuestionId] = obj;
} else {
acc[obj.QuestionId].myData = acc[obj.QuestionId].myData ?? []; // if myData is null or undefined, set it to an empty array
acc[obj.QuestionId].myData = acc[obj.QuestionId].myData.concat(obj.myData);
}
return acc;
}, {}));
console.log(result);
function mergeData(data) {
const acc = {}
data.forEach(x => {
const id = x.QuestionId
if (!acc[id]) acc[id] = x
else acc[id].myData = acc[id].myData.concat(x.myData)
})
return Object.values(acc)
}
I'd use a temporary object to:
- Loop over
array - For the current object;
- merge (
{...obj1, ...obj2}) current object toreson thetskey
- merge (
- Use
Object.valuesto convert it to the desired array
const array = [{ts: 1596232800, v1: 1}, {ts: 1596232860, v1: 2}, {ts: 1596232920, v1: 3}, {ts: 1596232800, b2: 10}, {ts: 1596232860, b2: 11}, {ts: 1596232920, b2: 12}, {ts: 1596232800, c3: 20}, {ts: 1596232860, c3: 21}, {ts: 1596232920, c3: 22} ];
let res = {};
array.forEach(a => res[a.ts] = {...res[a.ts], ...a});
res = Object.values(res);
console.log(res);
[
{
"ts": 1596232800,
"v1": 1,
"b2": 10,
"c3": 20
},
{
"ts": 1596232860,
"v1": 2,
"b2": 11,
"c3": 21
},
{
"ts": 1596232920,
"v1": 3,
"b2": 12,
"c3": 22
}
]
This can be solved using reduce function mdn.
const array = [
{ts: 1596232800, v1: 1},
{ts: 1596232860, v1: 2},
{ts: 1596232920, v1: 3},
{ts: 1596232800, b2: 10},
{ts: 1596232860, b2: 11},
{ts: 1596232920, b2: 12},
{ts: 1596232800, c3: 20},
{ts: 1596232860, c3: 21},
{ts: 1596232920, c3: 22}
];
const result = array.reduce((acc, value) => {
const fIndex = acc.findIndex(v => v.ts === value.ts);
if (fIndex >= 0) {
acc[fIndex] = { ...acc[fIndex],
...value
}
} else {
acc.push(value);
}
return acc;
}, []);
console.log(result);
You could use reduce with Object.keys to do that.
var arr = [
{id: 1, tech_id:11, action: 'swim'},
{id: 2, tech_id:11, action: 'run'},
{id: 3, tech_id:22, action: 'climb'},
{id: 4, tech_id:22, action: 'swim'},
{id: 5, tech_id:11, action: 'jump'},
]
let mergeObj = arr.reduce((p, c) => {
const {tech_id, ...otherData} = c;
if (!(tech_id in p)) {
p[tech_id] = {
data: []
}
}
p[tech_id].data.push(otherData)
return p
}, {})
mergeObj = Object.keys(mergeObj).map(key => {
return {
tech_id: key,
data: mergeObj[key].data
}
})
console.log(mergeObj);
You can use the Array reduce and Object Value function to get it done.
var arr = [
{id: 1, tech_id:11, action: 'swim'},
{id: 2, tech_id:11, action: 'run'},
{id: 3, tech_id:22, action: 'climb'},
{id: 4, tech_id:22, action: 'swim'},
{id: 5, tech_id:11, action: 'jump'},
]
const result = Object.values(arr.reduce((item, next) => {
if (!item[next.tech_id]) {
item[next.tech_id] = {
tech_id: next.tech_id,
data: []
};
}
item[next.tech_id].data.push(next);
return item;
}, {}));
console.log(result);
I'm trying to merge multiple objects in an array into one object if they share the same ID. For instance...
var Students = [
{
ID : 1,
Name : "John Doe",
SponserID : 421,
SponserName : "Mark"
},
{
ID : 1,
Name : "John Doe",
SponserID : 341,
SponserName : "James"
},
{
ID : 2,
Name : "James Law",
SponserID : 421,
SponserName : "Mark"
}
]I want to be able to combine the Obejcts with the same ID and make an object of the different properties in those objects so the result would look something like
var ModifiedStudents = [
{
ID : 1,
Name : "John Doe",
Sponsers : [
{
SponserID : 421,
SponserName : "Mark"
},
{
SponserID : 341,
SponserName : "James"
},
]
},
{
ID : 2,
Name : "James Law",
SponserID : 421,
SponserName : "Mark"
}
]You can simply use Array.reduce() to create a map, grouped by name and Object.values() on the map will give your the desired result:
let arr = [ { "name": "Blah", "description": "This is a description" }, { "name": "Foo", "description": "This is a description" }, { "name": "Bar", "description": "This is a description" }, { "name": "Blah", "description": "This is a description" }, { "name": "Test", "description": "This is a description" } ];
let result = Object.values(arr.reduce((a, {name,description})=>{
if(a[name])
a[name].description += "\n" + description;
else
a[name] = Object.assign({},{name,description});
return a;
},{}));
console.log(result);
You could use a lookup object to find duplicates:
const result = [], hash = {};
for(const {name, description} of input) {
if(hash[name]) {
hash[name].description += "\n" + description;
} else {
result.push(hash[name] = { name, description });
}
}
var arr = [
{
"abc": [
{
"name": "test",
"addr": "123",
}
]
},
{
"def": [
{
"first_name": "test",
"last_name": "test"
}
]
},
{
"def": [
{
"first_name": "test1",
"last_name": "test1"
}
]
}]
const result = arr.reduce((acc, curr) => {
const key = Object.keys(curr)[0]
const found = acc.find(i => i[key])
if (!found) {
acc.push(curr)
} else {
found[key] = [ ...found[key], ...curr[key] ]
}
return acc;
}, [])
console.log(result)
Code below should give the desired result.
ES6
arr.reduce((acc, curr) => {
const key = Object.keys(curr)[0]
const found = acc.find(i => i[key])
if (!found) {
acc.push(curr)
} else {
found[key] = [ ...found[key], ...curr[key] ]
}
return acc;
}, [])
ES5
arr.reduce(function (acc, curr) {
var key = Object.keys(curr)[0];
var found = acc.find(function (i) {
return i[key];
});
if (!found) {
acc.push(curr);
} else {
found[key] = [].concat(found[key], curr[key]);
}
return acc;
}, []);
using filter instead of find
arr.reduce(function (acc, curr) {
var key = Object.keys(curr)[0];
var found = acc.filter(function (i) {
return i[key];
})[0];
if (!found) {
acc.push(curr);
} else {
found[key] = [].concat(found[key], curr[key]);
}
return acc;
}, []);
Using object and array
var arr = [{
"abc": [{
"name": "test",
"addr": "123",
}]
},
{
"def": [{
"first_name": "test",
"last_name": "test"
}]
},
{
"def": [{
"first_name": "test1",
"last_name": "test1"
}]
}
]
var b = {}
arr.forEach(c => {
var key = Object.keys(c)[0]
var value = Object.values(c)[0]
if (!b[key]) b[key] = []
b[key].push(...value)
})
// b is resultant object
var c = []
Object.keys(b).forEach(v => {
let a = {};
a[v] = b[v];
c.push(a)
})
// c is converting object to array
console.log(c)
var obj1 = {name: "John", hobby: "Football"}
var obj2 = {hobby: "Basketball"}
var obj3 = {hobby: "Tennis"}
const merge = (obj1, obj2) => {
Object.keys(obj1).forEach(key => { if (obj2[key]) obj1[key] = [...[obj1[key]], obj2[key]].flat() })
}
merge(obj1, obj2)
merge(obj1, obj3)
console.log(obj1)
const obj1 = {name: "John", hobby: "Football"}
const obj2 = {hobby: "Basketball"}
const obj3 = {}
for (const key in obj1){
if (obj2[key] === undefined){
obj3[key] = obj1[key]
}else{
obj3[key] = [ obj1[key], obj2[key] ]
}
}
console.log(obj3)
Slightly different solution. Does not alter original objects.