given the following array structure:
[{ _id: '1234', characteristics: [[Object], [Object]]},
{ _id: '1234',characteristics: [[Object], [Object]]},
{ _id: '4567', characteristics: [[Object], [Object]]},
{ _id: '4567',characteristics: [ [Object], [Object]]},
{ _id: '4987',characteristics: [ [Object], [Object]]}]
how can I compare one array element with the next, and merge the object with the same id?
the end result is something like
[ { _id: '1234', characteristics: [ [Object], [Object] ,[Object], [Object] ]},
{ _id: '4567',characteristics: [ [Object], [Object] , [Object], [Object]]},
{ _id: '4987', characteristics: [ [Object], [Object] ] } ]
basically the objects inside both of the object with id of 1234 are merged together under characteristics.
I been staring at this for the past 2 hours, anyone have any idea? I'd prefer a more functional approach.
Edit : Solution that I am using based on Nenad Vracar's solution.
function mergeDupKey(data) {
var o = {}
return data.reduce(function(r, e) {
if (!o[e._id]) {
o[e._id] = e;
r.push(o[e._id]);
} else {
o[e._id].characteristics = o[e._id].characteristics.concat(e.characteristics);
}
return r;
}, [])
}
var g = mergeDupKey(data)`
You can use reduce()
with one helper object. You can also use concat()
instead of ...
and push()
like this
var data = [{ _id: '1234', characteristics: [[1], [2]]}, { _id: '1234',characteristics: [[3], [4]]}, { _id: '4567', characteristics: [[5], [6]]}, { _id: '4567',characteristics: [ [7], [8]]}, { _id: '4987',characteristics: [ [9], [10]]}]; var o = {} var result = data.reduce(function(r, e) { if (!o[e._id]) { o[e._id] = e; r.push(o[e._id]); } else { o[e._id].characteristics.push(...e.characteristics); } return r; }, []) console.log(result)
Use Array.prototype.reduce
and a hash table to group the properties - see demo below:
var array=[{_id:'1234',characteristics:[[1],[2]]},{_id:'1234',characteristics:[[3],[4]]},{_id:'4567',characteristics:[[5],[6]]},{_id:'4567',characteristics:[[7],[8]]},{_id:'4987',characteristics:[[9],[10]]}]; var result = array.reduce(function(hash) { return function(prev,curr){ if(hash[curr._id]) { curr.characteristics.forEach(function(e){ hash[curr._id].push(e); }); } else { hash[curr._id] = curr.characteristics; prev.push({_id: curr._id, characteristics:hash[curr._id]}) } return prev; }; }(Object.create(null)), []); console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}
This can be done with .reduce()
. There is no need for a helper object.
var data = [{ _id: '1234', characteristics: [[1], [2]]}, { _id: '1234',characteristics: [[3], [4]]}, { _id: '4567', characteristics: [[5], [6]]}, { _id: '4567',characteristics: [ [7], [8]]}, { _id: '4987',characteristics: [ [9], [10]]}]; var found = false; var result = data.reduce(function(prev, curr) { prev.forEach(function(obj) { if (obj._id == curr._id) { obj.characteristics = obj.characteristics.concat(curr.characteristics); found = true; } }); if (!found) prev.push(curr); found = false; return prev; }, []); console.log(result)
Using ES5 approach:
var lst = [{ _id: '1234', characteristics: [[Object], [Object]]},
{ _id: '1234',characteristics: [[Object], [Object]]},
{ _id: '4567', characteristics: [[Object], [Object]]},
{ _id: '4567',characteristics: [ [Object], [Object]]},
{ _id: '4987',characteristics: [ [Object], [Object]]}];
var result = [];
var findById = function(id) {
for (var i = 0; i < result.length; i++) {
var item = result[i];
if (item._id === id) {
return item;
}
}
var newitem = { _id: id, characteristics: [] };
result.push(newitem);
return newitem;
}
lst.forEach(function(item) {
var aux = findById(item._id);
aux.characteristics.concat(item.characteristics);
});
console.log(result);
Using ES6:
var lst = [{ _id: '1234', characteristics: [[Object], [Object]]},
{ _id: '1234',characteristics: [[Object], [Object]]},
{ _id: '4567', characteristics: [[Object], [Object]]},
{ _id: '4567',characteristics: [ [Object], [Object]]},
{ _id: '4987',characteristics: [ [Object], [Object]]}];
var result = [];
lst.forEach(item => {
var aux = result.find(it => it._id === item._id);
if (!aux) {
aux = { _id: item._id, characteristics: [] };
result.push(aux);
}
aux.characteristics.concat(item.characteristics);
});
console.log(result);
You may do as follows;
var data = [{ _id: '1234', characteristics: [["whatever"], ["whatever"]]}, { _id: '1234', characteristics: [["whatever"], ["whatever"]]}, { _id: '4567', characteristics: [["whatever"], ["whatever"]]}, { _id: '4567', characteristics: [["whatever"], ["whatever"]]}, { _id: '4987', characteristics: [["whatever"], ["whatever"]]}], lut = data.reduce((p,c) => p[c._id] ? (p[c._id].characteristics.push(...c.characteristics),p) : (p[c._id] = c, p), {}); result = Object.keys(lut) .map(k => lut[k]); console.log(result);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.