Javascript将对象合并到键 - >一组价值观

时间:2014-08-25 20:41:27

标签: javascript underscore.js

我使用下划线,我想知道是否有更有效的方法来完成以下操作 - 看起来这应该是下划线中的函数。

var obj1 = { test: 'hello' },
    obj2 = { test: 'hello2' };

var merged = {};
_.each(_.keys(obj1), function(key) { merged[key] = [obj1[key], obj2[key]]; });

console.log(merged);

此外的限制是obj2obj1中没有出现的任何键都不会被计算在内 - 如果我能得到类似于完全外连接的东西,那就更好了一方或另一方如果不存在则为空。此外,如果这不仅限于两个对象,那将是很好的。

4 个答案:

答案 0 :(得分:2)

您可以使用普通JS和多个对象执行此操作:

var merge = function() {
  return [].reduce.call(arguments, function(acc, obj) {
    Object.keys(obj).forEach(function(k) {
      acc[k] = (acc[k] || []).concat(obj[k])
    })
    return acc
  }, {})
}

var a = {
  prop: 1
}
var b = {
  prop: 2
}
var c = {
  prop: 3
}

console.log(merge(a, b, c)) //=> {prop: [1,2,3]}

答案 1 :(得分:1)

可能有更多的下划线方式,但它在普通的JS中是一个相当简单的功能:

function mergeObjects() {
  var merged = {};

  for ( var i = 0; i < arguments.length; ++i )
    {
      var o = arguments[i];

      for ( var f in o )
        if (o.hasOwnProperty(f))
          {
            merged[f] = merged[f] || [];
            merged[f].push(o[f]);
          }
    }

  return merged;
}

此版本接受任意数量的参数,假设它们是所有对象。

示例:http://codepen.io/paulroub/pen/sDcym

答案 2 :(得分:1)

我也会把帽子放在戒指上:

function merge(){
  var objects = arguments,
      merged = {},
      keys = _.union(_.flatten(_.map(objects, function(arg){ return _.keys(arg); })));
  _.each(keys, function(key){
      _.each(objects, function(obj){
          merged[key] = merged[key] || [];
          merged[key].push(obj.hasOwnProperty(key) ? obj[key] : null);
      });
  });
  return merged;
}

无法说出它的可读性或速度,因为我认为它不会在任何一个类别中获胜。但是,除了你自己的答案,我认为这是唯一一个真正符合所有要求的人。

示例:http://jsfiddle.net/z01ubsny/1/

答案 3 :(得分:0)

这是一个比我在原帖中提供的更好的解决方案,尽管我仍然不相信它是最优的。

 var objs = [{
   test: 'hello',
   test2: 'word',
   test3: 2
 }, {
   test: 'hello2',
   test0: 1
 }];

 var merged = _.chain(_.defaults.apply(_, objs))
   .keys()
   .map(function(k) {
     return [k, _.pluck(objs, k)]
   })
   .object()
   .value();

 console.log(merged);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>