如何使用相同的键聚合2个json数组的所有列

时间:2017-01-13 03:11:21

标签: javascript json

我想从

开始
var var1 = [
  {key:'key1',value1:'value11'},
  {key:'key2',value1:'value12'}
];

var var2 = [
  {key:'key1',value2:'value21'},
  {key:'key2',value2:'value22'}
];

到这里

var var3 = [
  {key:'key1',value1:'value11',value2:'value21'},
  {key:'key2',value1:'value12',value2:'value22'}
];

最简单的方法是什么?

4 个答案:

答案 0 :(得分:1)

使用underscore.js(您可以在控制台上测试它)

我会将其作为练习,使用_.filter_.map

将其设为单行
function extendArrayByKey(var1, var2) {
  for (obj of var1) {
    var key = obj.key;
    for (obj2 of var2) {
      if (obj2.key == key) {
        _.extend(obj, obj2);
      }
    }
  }
}

请注意,这会修改var1中的对象,并使用var2

中值的浅副本

答案 1 :(得分:1)

较慢的解决方案

一种解决方案是迭代遍历array1,并且对于每个对象,如果具有其键的对象已经存在于array2中,则将其合并。

此解决方案将具有恒定空间但是具有二次时间O(arr1.length) * O(arr2.length),因为对于array1中的每个对象,我们在array2中搜索匹配。

var var1=[{key:"key1",value1:"value11"},{key:"key2",value1:"value12"}],var2=[{key:"key1",value2:"value21"},{key:"key2",value2:"value22"}];

// O(N*M) time, O(1) space
function mergeQuadratic(arr1, arr2) {
  const result = [];

  arr1.forEach(obj1 => {
    // try to find a match for the current arr1 object by searching through arr2
    const obj2 = arr2.find(obj2 => obj2.key === obj1.key);

    // if we found a match, we can merge these two objects
    if (obj2) {
      result.push(Object.assign({}, obj1, obj2));
    }
  });

  return result;
}

console.log(mergeQuadratic(var1, var2));

ES5版本:

var var1=[{key:"key1",value1:"value11"},{key:"key2",value1:"value12"}],var2=[{key:"key1",value2:"value21"},{key:"key2",value2:"value22"}];

// O(N*M) time, O(1) space
function mergeQuadratic(arr1, arr2) {
  var result = [];
  arr1.forEach(function(obj1) {
    // try to find a match for the current arr1 object by searching through arr2
    var obj2 = arr2.find(function(obj2) {
      return obj2.key === obj1.key
    });

    // if we found a match, we can merge these two objects
    if (obj2) {
      result.push(Object.assign({}, obj1, obj2));
    }
  });

  return result;
}

console.log(mergeQuadratic(var1, var2));

更快的解决方案

提高速度的一个改进是权衡一些空间并从array2创建一个映射,这样我们就可以缩短匹配键的查找时间,使其具有线性运行时间O(array1.length) + O(array2.length)和线性空间{ {1}}:

O(array2.length)

ES5版本:

var var1=[{key:"key1",value1:"value11"},{key:"key2",value1:"value12"}],var2=[{key:"key1",value2:"value21"},{key:"key2",value2:"value22"}];

// O(N+M) time, O(N) space
function mergeLinear(arr1, arr2) {
  // create a map of key->obj for every object in arr2
  const map = arr2.reduce((map, curr) => {
    map.set(curr.key, curr);
    return map;
  }, new Map());

  const result = [];

  arr1.forEach(obj1 => {
    // check almost instantly if a matching object exists
    const obj2 = map.get(obj1.key); // <-- Constant time lookup

    // if we found a match, we can merge these two objects
    if (obj2) {
      result.push(Object.assign({}, obj1, obj2));
    }
  });

  return result;
}

console.log(mergeLinear(var1, var2));

答案 2 :(得分:1)

如果您的密钥总是像您提供的名称一样命名,那么这似乎是一个简单的合并。如果名称可以更改,则必须修改此解决方案。

此解决方案不会改变任何现有阵列。该函数返回一个新数组。

var var1 = [
  {key:'key1',value1:'value11'},
  {key:'key2',value1:'value12'}
];

var var2 = [
  {key:'key1',value2:'value21'},
  {key:'key2',value2:'value22'}
];


function mergeArrays(arr1, arr2) {
  var newArray = arr1;

  newArray.forEach(function (obj1) {
    arr2.forEach(function (obj2) {
      if (obj1.key === obj2.key) {
        obj1.value2 = obj2.value2;
      }
    });
  });

  return newArray;
}

var var3 = mergeArrays(var1, var2);

console.log(var3);

答案 3 :(得分:1)

对于好的浏览器(不是IE,但Object.assignArray#find的polyfill可用)

var var3 = var1.map(function(o1) {
    return Object.assign({}, o1, var2.find(function(o2) {
       return o2.key === o1.key;
    }));
});

或现代发言

var var3 = var1.map(o1 => Object.assign({}, o1, var2.find(o2 => o2.key === o1.key)));