【问题标题】:merging objects in javascript在javascript中合并对象
【发布时间】:2026-02-24 02:55:01
【问题描述】:

我有 2 个对象数组如下:

arr1 =  [ { 'v1': 'abcde',
    'pv_45': 13018, 
    'geolocation': '17.340291,76.842807'
   }]

arr2 =[{ 'v1':'abcde',
    'pv_50': 13010,    
    geolocation: '17.340291,76.842807'
    }]

我想将上面2个数组int0单based on condition that 'v1' and 'geolocation' should be same合并如下:

[{'v1':'abcde',
      'pv_45': 13018, 
      'pv_50': 13010,
      'geolocation': '17.340291,76.842807'}]

我使用了_.extend,但它不会盲目检查任何条件,它会合并。请分享你的想法。提前致谢。

【问题讨论】:

  • 两个数组可以包含超过 1 个元素吗?如果不是,自己编写代码应该很简单,否则可能会有点困难
  • @ RemyNL 有时可以..但不确定两个数组的长度是否相同..
  • groupBy geolocation,并合并结果组。

标签: javascript node.js object


【解决方案1】:

您可以使用 underscore js union and uniq 来做到这一点。

var mergedArray = _.uniq(_.union(c1, c2), false, function(item, key, a){ return item; });

【讨论】:

  • 谢谢,但我得到了输出..它没有合并。
  • 你得到的输出是什么?
  • [{'v1':'abcde', 'pv_45': 13018, '地理位置': '17.340291,76.842807'}]
  • 也许只尝试var mergedArray = _.union(c1, c2);
【解决方案2】:

使用纯 JavaScript 可以这样做:

var arr1 =  [ { 'v1': 'abcde',
    'pv_45': 13018, 
    'geolocation': '17.340291,76.842807'
  }],
  arr2 =[{ 'v1':'abcde',
    'pv_50': 13010,    
    geolocation: '17.340291,76.842807'
  }],
  mergeOnV1Geo = function (arr1, arr2) {
    var mergeObj = {},
      merge = function (item) {
        var key = item.v1 + ',' + item.geolocation;
        // if this is the first object with this key
        // create a new object and copy v1, geolocation info
        if (!mergeObj[key]) {
          mergeObj[key] = {
            v1: item.v1,
            geolocation: item.geolocation
          };
        }
        // add other props
        Object.keys(item).forEach(function (prop) {
          if (!prop.match(/v1|geolocation/)) {
            mergeObj[key][prop] = item[prop];
          }
        });
      };
    arr1.forEach(merge);
    arr2.forEach(merge);

    // map back into an array
    return Object.keys(mergeObj).map(function (key) {
      return mergeObj[key];
    });

  };

mergeOnV1Geo(arr1, arr2);

【讨论】:

  • 感谢您的宝贵时间。我有这个逻辑代码。但我需要一些有效的方法来实现这一点。
  • 我不知道您是否可以提高效率。此代码对每个输入数组进行一次传递,然后再对合并的数据进行一次传递以将其转换回数组。
  • @无用代码假设考虑不同长度的数组。会发生什么??
  • 数组的长度无关紧要。如果它们的长度不同,则代码的行为完全相同。 merge 对输入数组中的每个项目运行一次,然后将 mergeObj 转换为数组。更长的数组需要更多的时间来完成,但你使用的任何方法都会发生这种情况。使用 Underscore,您使用的每个 Underscore 方法将至少对数据进行一次传递。您可以使用 Underscore 用更少的代码编写它,但在性能方面可能会降低效率。
【解决方案3】:

您可以执行以下操作:

var arr3 = [].concat.apply([], arr1, arr2);
var temp =_.groupBy(arr3, 'geolocation');
var result = Object.keys(_.groupBy(arr3, 'geolocation')).map(function(x)  {  return _.extend.apply(0, p[x]); })

如果你更喜欢 ES-6 箭头函数,result 变为

Object.keys(_.groupBy(arr3, 'geolocation')).map((x) => _.extend.apply(0, p[x]);)

【讨论】:

    【解决方案4】:

    ES6:使用spread operatorreduce

    arr1 =  [{ v1: 'abcde',
      pv_45: 13018, 
      geolocation: '17.340291,76.842807'
    }]
    
    arr2 =[{ v1:'abcde',
      pv_50: 13010,    
      geolocation: '17.340291,76.842807'
    }]
    
    // Keys to be grouped i.e whose values should be equal
    groupableKeys = ['v1', 'geolocation'];
    
    // Reducer that creates an Object with Key as the
    // groupable key values value1::value2 and Value as
    // the list of objects whose v1 and geolocation are same
    groupableReducer = (a, b) => {
      const uniqKey = groupableKeys.map(key => b[key]).join("::");
      a[uniqKey] = [...(a[uniqKey] || []), b];
      return a;
    }
    
    // Merges two objects using the spread operator
    mergableReducer = (a, b) => ({...a, ...b})
    
    // Merge two arrays and start processing
    groupableKeyObject = [...arr1, ...arr2].reduce(groupableReducer, {})
    
    output = Object.keys(groupableKeyObject)
                   .map(key => 
                       groupableKeyObject[key].reduce(mergableReducer, {})
                    )
    
    console.log(output);

    【讨论】: