【问题标题】:Merging/extend javascript object arrays based on join of a key property in each基于每个键属性的连接合并/扩展javascript对象数组
【发布时间】:2011-08-28 21:08:56
【问题描述】:

我想通过首先加入 id 属性来合并以下对象数组

var arr1 = [{
    id: 1,
    name: 'fred',
    title: 'boss'
},{
    id: 2,
    name: 'jim',
    title: 'nobody'
},{
    id: 3,
    name: 'bob',
    title: 'dancer'
}];

var arr2 = [{
    id: 1,
    wage: '300',
    rate: 'day'
},{
    id: 2,
    wage: '10',
    rate: 'hour'
},{
    id: 3,
    wage: '500',
    rate: 'week'
}];

所以结果是

[{
    id: 1,
    name: 'fred',
    title: 'boss',
    wage: '300',
    rate: 'day'
},{
    id: 2,
    name: 'jim',
    title: 'nobody',
    wage: '10',
    rate: 'hour'
},{
    id: 3,
    name: 'bob',
    title: 'dancer',
    wage: '500',
    rate: 'week'
}]

我想避免使用 js 框架(如果可能的话),尽管 ExtJs 已经是项目的一部分。 目前我有一个带有内循环的循环,如果键匹配,它会复制属性并跳出内循环以开始下一个外循环。

有更好的建议吗?

【问题讨论】:

  • 这在.extend 的帮助下使用jQuery 相对容易做到——无论如何,你能展示一下你目前拥有的代码吗?它有效吗?您在寻找优化的解决方案吗?

标签: javascript arrays object merge


【解决方案1】:

试试这个...

var arr1 = [{
    id: 1,
    name: 'fred',
    title: 'boss'
},{
    id: 2,
    name: 'jim',
    title: 'nobody'
},{
    id: 3,
    name: 'bob',
    title: 'dancer'
}];

var arr2 = [{
    id: 1,
    wage: '300',
    rate: 'day'
},{
    id: 2,
    wage: '10',
    rate: 'hour'
},{
    id: 3,
    wage: '500',
    rate: 'week'
}];

let arr5 = arr1.map((item, i) => Object.assign({}, item, arr2[i]));
console.log(arr5)

【讨论】:

    【解决方案2】:

    像这样?

    var combined = [];
    function findSecond(id,second){
        for (var i=0;i<second.length;i++){
            if(second[i].id === id){
                return second[i];
            }
        }
        return null
    }
    
    while (el = arr1.pop()){
        var getSec = findSecond(el.id,arr2);
        if (getSec){
            for (var l in getSec){
                if (!(l in el)) {
                    el[l] = getSec[l];
                }
            }
            combined.push(el);
        }
    }
    

    如果数组的长度相同,并且 id 相同,则可以进行更简单的合并:

    function merge(a1,a2) {
        var i = -1;
        while ((i = i+1)<a1.length)  {
         for (var l in a2[i]) {
                if (!(l in a1[i] )) {
                    a1[i][l] = a2[i][l];
                }
         }
        }
       return a1; 
    }
    

    这是working example

    [编辑 2016/07/30] 添加了一个使用更多功能方法的 sn-p,并且基于 @djangos 评论,添加了一种组合 both 数组的额外方​​法。

    (function() {
        var alert = function(str) {document.querySelector('#result').textContent += str + '\n';};
        var arrays = getArrays();
      
        alert('Combine on id (shared id\'s):')
        alert(JSON.stringify(combineById(arrays.arr1, arrays.arr2), null, ' '));
      
        alert('\nCombine on id (all id\'s):')
        alert(JSON.stringify(combineBothById(arrays.arr1, arrays.arr2), null, ' '));
      
        // for combineBothById the parameter order isn't relevant
        alert('\nCombine on id (all id\'s, demo parameter order not relevant):')
        alert(JSON.stringify(combineBothById(arrays.arr2, arrays.arr1), null, ' '));
      
        // combine first array with second on common id's
        function combineById(arr1, arr2) {
          return arr1.map(
              function (el) {
                    var findInB = this.filter(function (x) {return x.id === el.id;});
                    if (findInB.length) {
                        var current = findInB[0];
                        for (var l in current) {
                            if (!el[l]) {el[l] = current[l];}
                        }
                    }
                    return el;
              }, arr2);
        }
    
        // combine first array with second on all id's
        function combineBothById(arr1, arr2) {
            var combined = arr1.map(
                function (el) {
                    var findInB = this.filter(function (x) {return x.id === el.id;});
                    if (findInB.length) {
                        var current = findInB[0];
                        for (var l in current) {
                            if (!el[l]) {el[l] = current[l];}
                        }
                    }
                    return el;
                }, arr2);
            combined = combined.concat(arr2.filter(
                function (el) {
                    return !this.filter(function (x) {return x.id === el.id;}).length;
                }, combined));
            return combined;
        }
      
        function getArrays() {
            return {
                arr1: [{
                    id: 1,
                    name: 'fred',
                    title: 'boss'
                }, {
                    id: 2,
                    name: 'jim',
                    title: 'nobody'
                }, {
                    id: 3,
                    name: 'bob',
                    title: 'dancer'
                }],
                arr2: [{
                    id: 1,
                    wage: '300',
                    rate: 'day'
                }, {
                    id: 2,
                    wage: '10',
                    rate: 'hour'
                }, {
                    id: 4,
                    wage: '500',
                    rate: 'week'
                }]
            };
        }
    }());
    &lt;pre id="result"&gt;&lt;/pre&gt;

    【讨论】:

    • 我正在寻找相同的东西,但有点不同,请查看jsfiddle.net/ZaJ4x/35。我期望结果的 id 为 1,2,3,4
    • 您似乎想从两个数组中合并。也许这个小提琴提供了一个解决方案:jsfiddle.net/7aobwxvv
    • @django 也在答案中添加了一个 sn-p
    【解决方案3】:

    您可以通过 id 列与Alasql library 合并两个数组:

    var res = alasql('SELECT * FROM ? arr1 JOIN ? arr2 USING id', [arr1,arr2]);
    

    试试这个例子at jsFiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 2015-06-08
      • 2015-12-05
      • 1970-01-01
      • 2018-04-01
      • 2021-01-27
      相关资源
      最近更新 更多