在JS中扩展和合并两个数组(包含对象)

时间:2013-05-30 05:50:27

标签: javascript underscore.js

所以我有阵列A:

   var arrA = [{
      name: 'twitter',
      location: 0,
      hidden: false,
      href: "https://twitter.com/i/connect"
    }, {
      name: 'medium',
      location: 1,
      hidden: false,
      href: "https://medium.com/me/activity"
    }
  ];

阵列B:

var arrB = [{
      name: 'twitter',
      location: 1,
      hidden: false
    }, {
      name: 'medium',
      location: 0,
      hidden: false
    }
  ];

我怎样才能得到一个如下所示的数组:

var newArr = [{
      name: 'twitter',
      location: 1,
      hidden: false,
      href: "https://twitter.com/i/connect"
    }, {
      name: 'medium',
      location: 0,
      hidden: false,
      href: "https://medium.com/me/activity"
    }
  ];

所以,这里有两件事,1。location值来自arrB,而不是arrA,2。newArr的对象现在包含{{ 1}}密钥,取自href

所以我需要从第二个数组中获取值,但是从第一个数组维护新键。

我可以使用underscore.js函数执行此操作(我现在正在使用_.extend,但如果它是新的,它不会保留arrA的密钥)?

4 个答案:

答案 0 :(得分:1)

您可以加入两个数组并使用Alasql库选择适当的属性:

var res1 = alasql('SELECT arrA.name, arrB.location, arrA.href, arrB.hidden \
            FROM ? arrA JOIN ? arrB USING name', [arrA,arrB]);

或Underscore _.extend版本:

alasql.fn.extend = _.extend.bind(_);
var res2 = alasql('SELECT COLUMN extend(arrA._, arrB._) 
                   FROM ? arrA JOIN ? arrB USING name', [arrA,arrB]);

试试这些例子at jsFiddle

答案 1 :(得分:0)

var newArr=[];
$.each(arrA, function(index, value) {
$.extend(value, arrB[index]);
newArr[index]=value
});

http://jsfiddle.net/QZzZM/

答案 2 :(得分:0)

不确定下划线是否具有合并这样的数组的功能,但您可以编写如下给出的函数来有条件地合并数组

Array.prototype.conditionalMerge = function(arr, props){

    var merged = [];

    for(var i=0; i<this.length;i++){
        var item = {};
        for(var attr in this[i]){
            item[attr] = (props[attr])?arr[i][attr]:this[i][attr];
        }
        merged.push(item);
    }

    return  merged;
}

arrA.conditionalMerge(arrB, {location:true})

答案 3 :(得分:0)

您可以将arrA中的条目“映射”为与arrB中相应条目合并的条目。在下划线:

_.map(arrA, function(a) {
    return _.extend(a, _.find(arrB, function(b) {
        return a.name === b.name;
    }));
});

此解决方案具有以下特征:

  1. 对象可以在两个数组中以任何顺序出现;他们的名字匹配。
  2. 将复制数组b中对象的任何额外属性。
  3. 在原生JS中

    arrA.map(function(a) {
        return Object.assign(a, arrB.find(function(b) {
            return a.name === b.name; 
        }));
    });
    

    Object.assignArray.find,如果不可用,可以进行填充。例如,这是find的版本:

    Array.prototype.find = function(callback) {
        for (var i = 0; i < this.length; i++ ) {
            if (callback(this[i], i, this)) return this[i];
        }
     });