简体   繁体   English

基于每个键属性的连接合并/扩展javascript对象数组

[英]Merging/extend javascript object arrays based on join of a key property in each

I am wanting to merge the following object arrays, by first joining on the id property我想合并以下对象数组,首先加入 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'
}];

So the result would be所以结果是

[{
    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'
}]

I would like to avoid using js frameworks (if possible), although ExtJs is already part of the project.我想避免使用 js 框架(如果可能的话),尽管 ExtJs 已经是项目的一部分。 AT the moment I have a loop with an inner loop that if the keys match it copies the properties and breaks out of the inner loop to start the next outer loop.目前我有一个带有内循环的循环,如果键匹配,它会复制属性并跳出内循环以开始下一个外循环。

Any better suggestions?有什么更好的建议吗?

Like this?像这样?

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

If the arrays have the same length, and the id's are equal, a simpler merge will do:如果数组具有相同的长度,并且 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; 
}

Here's a working example这是一个工作示例

[ Edit 2016/07/30 ] Added a snippet using more functional approach and, based on @djangos comment, an extra method to combine both arrays. [编辑 2016/07/30 ] 添加了一个使用更多功能方法的片段,并且基于@djangos 评论,添加了一个额外的方法来组合两个数组。

 (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' }] }; } }());
 <pre id="result"></pre>

You can merge two arrays by id column with Alasql library:您可以使用Alasql库通过 id 列合并两个数组:

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

Try this example at jsFiddle .在 jsFiddle试试这个例子。

try this...尝试这个...

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)

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

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