简体   繁体   English

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

[英]Javascript merge objects to key -> set of values

I'm using underscore, and I'm wondering if there's a more efficient way of accomplishing the following - seems like this should be a function in underscore. 我正在使用下划线,我想知道是否有一种更有效的方法来完成以下任务-似乎这应该是下划线功能。

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

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

console.log(merged);

Also the limitations of this are that any keys in obj2 not present in obj1 will not be counted - it would be nice if I could get something akin to a full outer join, where the value of one side or the other will be null if it doesn't exist. 此外,这样做的局限性在于,不计算obj1不存在的obj2中的任何键-如果我能得到类似于完全外部联接的东西,那将是很好的,如果一侧或另一侧的值为null不存在。 Also, it would be nice if this wasn't limited to two objects. 另外,如果这不限于两个对象,那将是很好的。

You can do this with plain JS, and multiple objects: 您可以使用普通的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]} 

There may be a more underscore-ish way to do it, but it's a fairly straightforward function in plain JS: 可能有更多的下划线方式,但这是普通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;
}

This version accepts any number of arguments, assuming they're all objects. 这个版本接受任何数量的参数,假设它们都是对象。

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

I'll throw my hat in the ring here as well: 我也会在这里戴上帽子:

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

Can't speak for it's readability or speed, as I don't think it wins in either category. 不能说它的可读性或速度,因为我认为它在任何一个类别中都不胜。 However, besides your own answer I think this is the only one that actually meets all of the requirements. 但是,除了您自己的答案,我认为这是唯一实际满足所有要求的答案。

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

Here's a better solution than what I provided in my original post, though I'm still not convinced it's optimal. 比起我最初的帖子中提供的解决方案,这是一个更好的解决方案,尽管我仍然不相信它是最佳的。

  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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM