【问题标题】:Find duplicate object values in an array and merge them - JAVASCRIPT在数组中查找重复的对象值并将它们合并 - JAVASCRIPT
【发布时间】:2014-12-27 05:05:49
【问题描述】:

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

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}]

【问题讨论】:

    标签: javascript arrays sorting duplicates


    【解决方案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);
    });
    

    【讨论】:

    • 谁有更简单、更短的解决方案? ;)
    【解决方案2】:

    我不确定您是否正在寻找纯 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,但一个具有@987654323 的值@ 和另一个值为9)。照原样,数组中后面出现的任何对象都将优先。

    【讨论】:

    • 嘿,非常感谢,这解决了问题:) 目前数据没有同一台机器的两个实例,所以这应该不是问题
    【解决方案3】:
    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/

    这要快得多:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-14
      • 2019-03-17
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      • 2016-07-21
      相关资源
      最近更新 更多