在数组中查找重复的对象值并合并它们 - JAVASCRIPT

时间:2014-10-30 23:27:23

标签: javascript arrays sorting duplicates

我有一个包含某些重复属性的对象数组:以下是数组样本:

var jsonData = [{x:12, machine1: 7}, {x:15, machine2:7},{x:12, machine2: 8}];

所以我需要的是将对象与x的相同值合并,如下面的数组:

var jsonData = [{x:12, machine1:7, machine2:8}, {x:15, machine2:7}]

3 个答案:

答案 0 :(得分:1)

我喜欢lodash库。

https://lodash.com/docs#groupBy

_.groupBy(jsonData, 'x')产生:

12: [ {x=12, machine1=7}, {x=12, machine2=8} ],
15: [ {x=15, machine2=7} ]

您想要的结果是这样实现的:

var jsonData = [{x:12, machine1: 7}, {x:15, machine2:7},{x:12, machine2: 8}];
var groupedByX = _.groupBy(jsonData, 'x');
var result = [];
_.forEach(groupedByX, function(value, key){
   var obj = {};
   for(var i=0; i<value.length; i++) {
     _.defaults(obj, value[i]);
   }
   result.push(obj);
});

答案 1 :(得分:0)

我不确定你是否在寻找纯JavaScript,但如果你是,那么这是一个解决方案。它在嵌套方面有点沉重,但它完成了工作。

// Loop through all objects in the array
for (var i = 0; i < jsonData.length; i++) {

  // Loop through all of the objects beyond i
  // Don't increment automatically; we will do this later
  for (var j = i+1; j < jsonData.length; ) {

    // Check if our x values are a match
    if (jsonData[i].x == jsonData[j].x) {

      // Loop through all of the keys in our matching object
      for (var key in jsonData[j]) {

        // Ensure the key actually belongs to the object
        // This is to avoid any prototype inheritance problems
        if (jsonData[j].hasOwnProperty(key)) {

          // Copy over the values to the first object
          // Note this will overwrite any values if the key already exists!
          jsonData[i][key] = jsonData[j][key];
        }
      }

      // After copying the matching object, delete it from the array
      // By deleting this object, the "next" object in the array moves back one
      // Therefore it will be what j is prior to being incremented
      // This is why we don't automatically increment
      jsonData.splice(j, 1);
    } else {
      // If there's no match, increment to the next object to check
      j++;
    }
  }
}

请注意,此示例中没有防御性代码;你可能想要添加一些检查,以确保你传递的数据格式正确,然后传递它。

还要记住,您可能必须决定如何处理两个键重叠但匹配的实例(例如,两个对象都有machine1,但其中一个具有值{ 5和另一个值9)。原样,数组中稍后出现的任何对象都将优先。

答案 2 :(得分:0)

const mergeUnique = (list, $M = new Map(), id) => {
  list.map(e => $M.has(e[id]) ? $M.set(e[id], { ...e, ...$M.get(e[id]) }) : $M.set(e[id], e));
  return Array.from($M.values());
};
在你的情况下,

id将是x

我使用电子邮件创建了一个jsperf作为标识符:https://jsperf.com/mergeobjectswithmap/

它快得多:)