简体   繁体   中英

how to traverse and compare object inside an array elements in javascript

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM