Javascript将对象合并到key ->一组值

Javascript merge objects to key -> set of values

本文关键字:一组 对象 合并 key Javascript      更新时间:2023-09-26

我正在使用下划线,我想知道是否有一种更有效的方法来完成以下任务-似乎这应该是一个下划线的函数。

var obj1 = { test: 'hello' },
    obj2 = { test: 'hello2' };
var merged = {};
_.each(_.keys(obj1), function(key) { merged[key] = [obj1[key], obj2[key]]; });
console.log(merged);

这样做的限制是obj2中不存在于obj1中的任何键都不会被计数-如果我能得到类似于完整的外连接的东西,如果不存在,一方或另一方的值将为空,那将是很好的。此外,如果这不是仅限于两个对象就好了。

你可以用普通的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]}

可能有一种更加下划线的方法,但在纯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

我也想试试:

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/

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

 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>