【问题标题】:Javascript obejct merge+add algorithmJavascript对象合并+添加算法
【发布时间】:2016-03-23 14:14:10
【问题描述】:

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

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

然后,我想到了一个“新想法”——使用哈希函数:

  1. 获取 obj1 和 obj2 的“键”的哈希值。
  2. 使用它们的哈希值作为数组的索引,将 obj1 和 obj2 的“值”插入或添加到新数组中。
  3. 将数组变成新对象。

我想知道的:

  1. 有没有类似 mergeAdd(obj1, obj2) 的库?
  2. 我的“新想法”比 mergeAdd(obj1, obj2) 快吗?
  3. mergeAdd 最快的算法是什么?

谢谢!

【问题讨论】:

  • O(nlogn) 用于合并和排序。

标签: javascript algorithm javascript-objects


【解决方案1】:

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

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>');

【讨论】:

    【解决方案2】:

    你会使用 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];
    });
    

    工作小提琴:https://jsbin.com/rogada/edit?js,console

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

    【讨论】:

      【解决方案3】:

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

      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

      【讨论】:

        猜你喜欢
        • 2016-09-05
        • 1970-01-01
        • 2019-06-13
        • 2015-11-19
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 2015-12-16
        相关资源
        最近更新 更多