Javascript对象合并+添加算法

Javascript obejct merge+add algorithm

我试图像这样合并和添加这两个对象:

obj1 = {
  jpg: 1,
  gif: 3,
}

obj2 = {
  jpg: 1,
  avi: 5,
}

obj3 = mergeAdd(obj1, obj2);
// obj3 = {
//   jpg: 2,
//   gif: 3,
//   avi: 5,
// }

首先,我创建了这个需要 O(n^2) 次点赞的对象:

for (let foo in obj1) {
  for (let bar in obj2) {
    if (foo === bar) {
      // Exists : Add count
      obj1[bar] += obj2[bar];
    } else {
      // Don`t Exists : Copy from obj2
      obj1[bar] = obj2[bar];
    }
  }
}

然后,我想到了一个 'new idea' - 使用散列函数:

  1. 获取 obj1 和 obj2 的 'key' 的哈希值。
  2. 使用散列值作为数组索引,将 obj1 和 obj2 的 'value' 插入或添加到新数组。
  3. 将数组变成新对象。

我想知道的:

  1. 有没有类似mergeAdd(obj1, obj2)的库?
  2. 我的 'new idea' 比 mergeAdd(obj1, obj2) 快吗?
  3. 执行合并添加最快的算法是什么?

谢谢!

你会用ES6吗?您可以使用新的 Object.assign() 方法轻松做到这一点:

let newObj = Object.assign({}, obj1, obj2);

没有 ES6:

var newObj  = {};
obj1 = {
  jpg: 1,
  gif: 3,
};

obj2 = {
  jpg: 1,
  avi: 5,
};
Object.keys(obj1).forEach(function(k) {
    newObj[k] = obj1[k];
});
Object.keys(obj2).forEach(function(e) {
    newObj[e] = obj2[e];
});

工作fiddle:https://jsbin.com/rogada/edit?js,console

取自:http://es6-features.org/#ObjectPropertyAssignment

具有线性复杂度的解决方案。

var obj1 = { jpg: 1, gif: 3, },
    obj2 = { jpg: 1, avi: 5, },
    merged = function (array) {
        var r = {};
        array.forEach(function (a) {
            Object.keys(a).forEach(function (k) {
                r[k] = (r[k] || 0) + a[k];
            });
        });
        return r;
    }([obj1, obj2]);

document.write('<pre>' + JSON.stringify(merged, 0, 4) + '</pre>');

通用recursive/functional 解决方案。获取一组对象并将每个对象合并到一个输出对象中。虽然不知道与其他答案相比它的性能如何 - 它可能非常糟糕。

function addValues(obj) {
  return function (p, c) {
    p[c] = (p[c] || 0) + obj[c];
    return p;
  }
}

function mergeObject(obj, out) {
  return Object.keys(obj).reduce(addValues(obj), out);
}

function processArray(arr, fn, out) {
  out = out || {};
  if (!arr.length) return out;
  out = fn(arr.shift(), out);
  return processArray(arr, fn, out);
}

var arr = [{ jpg: 1, gif: 3 }, { jpg: 1, avi: 5, }];
processArray(arr, mergeObject); // { jpg: 2, gif: 3, avi: 5 }

DEMO