【问题标题】:How to merge two arrays of JSON objects - removing duplicates and preserving order in Javascript/jQuery?如何合并两个 JSON 对象数组 - 在 Javascript/jQuery 中删除重复项并保留顺序?
【发布时间】:2012-02-26 10:11:58
【问题描述】:

jsfiddle 链接:http://jsfiddle.net/vN6fn/1/

假设我有这两个对象:

var obj1 = { data: [ 
                      {id:1, comment:"comment1"},
                      {id:2, comment:"comment2"},
                      {id:3, comment:"comment3"}
                   ] }

var obj2 = { data: [ 
                      {id:2, comment:"comment2"},
                      {id:3, comment:"comment3"},
                      {id:4, comment:"comment4"}
                   ] }

最终的对象应该是这样的:

var final = { data: [ 
                      {id:1, comment:"comment1"},
                      {id:2, comment:"comment2"},
                      {id:3, comment:"comment3"},
                      {id:4, comment:"comment4"}
                   ] }

以下是一些需要考虑的事项:

  • obj1 和 obj2 可能有也可能没有重复

$.extend() 替换对象,$.merge() 不删除重复项(我知道我可以执行 for 循环,但我正在寻找更好的方法来执行此操作)。

【问题讨论】:

  • 不会保留顺序均值 (3, 4, 5, 1, 2),因为对象 1 是第一个?
  • 对不起,我可以更改对象的编号。
  • @shershames 嗯,这并没有消除我的困惑。你这是什么意思?
  • 没有某种循环就无法做到这一点。这个问题也可能是stackoverflow.com/questions/3629817/…的重复
  • @sgarrett:但问题是,事实上,“如何合并两个数组”,ergo,可能是上述问题的重复。也许OP并不完全确定如何解决这个问题。我刚刚进行了搜索,然后出现了一个标题几乎相同的问题。物有所值。

标签: javascript jquery json


【解决方案1】:

你可以使用$.merge然后遍历并去除重复,然后排序。

$.merge(obj1.data, obj2.data);

var existingIDs = [];
obj1.data = $.grep(obj1.data, function(v) {
    if ($.inArray(v.id, existingIDs) !== -1) {
        return false;
    }
    else {
        existingIDs.push(v.id);
        return true;
    }
});

obj1.data.sort(function(a, b) {
    var akey = a.id, bkey = b.id;
    if(akey > bkey) return 1;
    if(akey < bkey) return -1;
    return 0;
});

【讨论】:

    【解决方案2】:

    http://jsfiddle.net/J9EpT/

    function merge(one, two){
      if (!one.data) return {data:two.data};
      if (!two.data) return {data:one.data};
      var final = {data:one.data};
      // merge
      for(var i = 0 ; i < two.data.length;i++){
          var item = two.data[i];
          insert(item, final);
      }
      return final;
    }
    
    
    function insert(item, obj){
        var data = obj.data;
        var insertIndex = data.length;
        for(var i = 0; i < data.length; i++){
            if(item.id == data[i].id){
               // ignore duplicates
               insertIndex = -1;
               break;
            } else if(item.id < data[i].id){
               insertIndex = i;
               break;
            }
        }
        if(insertIndex == data.length){
            data.push(item);
        } else if(insertIndex != -1) {
            data.splice(insertIndex,0,item);
        }
    }
    
    var final = merge(obj1, obj2);
    

    【讨论】:

      【解决方案3】:

      这是一个直接的 jQuery 解决方案:

      function mergeDeep(o1, o2) {
          var tempNewObj = o1;
      
          //if o1 is an object - {}
          if (o1.length === undefined && typeof o1 !== "number") {
              $.each(o2, function(key, value) {
                  if (o1[key] === undefined) {
                      tempNewObj[key] = value;
                  } else {
                      tempNewObj[key] = mergeDeep(o1[key], o2[key]);
                  }
              });
          }
      
          //else if o1 is an array - []
          else if (o1.length > 0 && typeof o1 !== "string") {
              $.each(o2, function(index) {
                  if (JSON.stringify(o1).indexOf(JSON.stringify(o2[index])) === -1) {
                      tempNewObj.push(o2[index]);
                  }
              });
          }
      
          //handling other types like string or number
          else {
              //taking value from the second object o2
              //could be modified to keep o1 value with tempNewObj = o1;
              tempNewObj = o2;
          }
          return tempNewObj;
      };
      

      Demo 带有复杂的对象。我已经把它变成了一篇博文,展示了 jQuery 的 .extend() 和我的脚本 here 之间的区别。

      【讨论】:

        【解决方案4】:

        合并两个删除重复的对象数组

        • 使用 Es6 ma​​p() 和 filter() 方法

        var obj1 = { data: [ 
                              {id:1, comment:"comment1"},
                              {id:2, comment:"comment2"},
                              {id:3, comment:"comment3"}
                           ] }
        
        var obj2 = { data: [ 
                              {id:2, comment:"comment2"},
                              {id:3, comment:"comment3"},
                              {id:4, comment:"comment4"}
                            ]}
        let obj3 = [...obj1.data, ...obj2.data]
        
        function mergeUniqueArray(arr, comp) {
        
          let unique = arr
            .map(item => item[comp])
        
             // store the keys of the unique objects
            .map((item, i, final) => final.indexOf(item) === i && i)
        
            // eliminate the duplicate keys & store unique objects
            .filter(item => arr[item]).map(item => arr[item]);
            
           return unique;
        }
        
        console.log(mergeUniqueArray(obj3,'id'));

        【讨论】:

          猜你喜欢
          • 2010-12-07
          • 1970-01-01
          • 2016-07-26
          • 2017-07-21
          • 2021-05-09
          • 2020-05-08
          • 2022-01-19
          相关资源
          最近更新 更多