简体   繁体   中英

Merge objects in array based on property

I have an array like so which i am trying to merge so any object that has the name property the same will after the merge contain a list of merged objects

var array = [ 
    {name: "One",
     myList: [Object1, Object2]
    },
    {name: "Two",
     myList: [Object3, Object4]
     },
     {name: "One",
     myList: [Object5, Object6]
     }
]

How do i merge the two 'One' objects so i get something like

var array = [ 
    {name: "One",
     myList: [Object1, Object2, Object5, Object6]
    },
    {name: "Two",
     myList: [Object3, Object4]
     }
]

looking to do this in vanilla javascript

Using reduce :

var merged = array.reduce(function(list, obj) {
    var found = false;
    for (var i = 0; i < list.length; i++) {
        if (list[i].name == obj.name) {
            list[i].myList = list[i].myList.concat(obj.myList);
            found = true;
            break;
        }
    }

    if (!found) {
        list.push(obj);
    }

    return list;
}, []);

Firstly you could remove the duplicate entries and organize the objects inside the myList array. Then, return an array of objects with specified keys, based on the ordered object from the first step.

 var array = [{name:"One",myList:['Object1','Object2']},{name:"Two",myList:['Object3','Object4']},{name:"One",myList:['Object5','Object6']}], obj = {}; array.forEach(function(v) { obj[v.name] = (obj[v.name] || []).concat(v.myList) }); var arr = Object.keys(obj).reduce(function(s,a) { s.push({name: a, myList: obj[a]}); return s; }, []); console.log(arr); 

Another approach using Lodash with just chain and reduce

var array = [
    { name: "One", myList: ["Object1", "Object2"] },
    { name: "Two", myList: ["Object3", "Object4"] },
    { name: "One", myList: ["Object5", "Object6"] }
  ];

  const newArray = _.chain(array)
    .reduce((acc, currentValue) => {
      acc[currentValue.name] = (acc[currentValue.name] || []).concat(
        currentValue.myList
      );
      return acc;
    }, {})
    .reduce((acc, currentValue, key) => {
      acc.push({ name: key, myList: currentValue }); 
      return acc;
    }, [])
    .value();

  console.log(newArray);

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