2015-04-22 144 views
1

假设我有以下阵列:合并阵列

var first = [ 
    { id: 1, name: 'first' }, 
    { id: 2, name: 'second' }, 
    { id: 3, name: 'third' } 
] 

var second = [ 
    { id: 2, field: 'foo2' }, 
    { id: 3, field: 'foo3' }, 
    { id: 4, field: 'foo4' } 
] 

var third = [ 
    { id: 2, data: 'some2' }, 
    { id: 5, data: 'some5' }, 
    { id: 6, data: 'some6' } 
] 

我想合并他们得到以下结果:

var result = [ 
    { id: 1, name: 'first', field: undefined, data: undefined }, 
    { id: 2, name: 'second', field: 'foo2', data: 'some2' }, 
    { id: 3, name: 'third', field: 'foo3', data: undefined }, 
    { id: 4, name: undefined, field: 'foo4', data: undefined }, 
    { id: 5, name: undefined, field: undefined, data: 'some5' }, 
    { id: 6, name: undefined, field: undefined, data: 'some6' } 
] 

我怎么会用JavaScript做呢?

+1

可能重复[如何合并在Javascript两个数组并删除重复的项目](http://stackoverflow.com/questions/1584370/how-to-merge-two-arrays-in-javascript-and-de-duplicate-items) –

+0

'concat'不会这样做。他不只是增加物品,他还希望场地的结合。哦,无论谁输入'concat'删除评论。那么别介意我的。 – deitch

+0

@VigneswaranMarimuthu concat不适合我的情况,因为我不想简单地合并数组。我想合并他们的项目 – JuniorThree

回答

0

没有简单的解决方案,你想要什么。这是我的建议。

var first = [ 
 
    { id: 1, name: 'first' }, 
 
    { id: 2, name: 'second' }, 
 
    { id: 3, name: 'third' } 
 
] 
 

 
var second = [ 
 
    { id: 2, filed: 'foo2' }, 
 
    { id: 3, field: 'foo3' }, 
 
    { id: 4, field: 'foo4' } 
 
]; 
 

 
var third = [ 
 
    { id: 2, data: 'some2' }, 
 
    { id: 4, data: 'some4' }, 
 
    { id: 6, data: 'some6' } 
 
]; 
 

 
var result = {}; 
 
first.concat(second,third).forEach(function(item){ 
 
    var id = item.id; 
 
    var row = result[id]; 
 
    if(!row){ 
 
     result[id] = item; 
 
     return; 
 
    } 
 
    for(var column in item){ 
 
     row[column] = item[column]; 
 
    } 
 
}); 
 
var finalResult = Object.keys(result).map(function(id){ 
 
    return result[id]; 
 
}); 
 
console.log(finalResult);

+0

它看起来不错,但在finalResult我得到每个项目只有领域,但是我想要得到来自每个项目的联盟。例如,第一,第二和第三个数组包含id = 2的项目,并且我想在finalResult中获得以下内容:{id:2,name:'second',field:'foo2',data:'some2'}但是我得到{id:2,name:'second'} – JuniorThree

+0

@JuniorThree我的不好。它现在就像你期望的那样工作。 – Lewis

0

你应该得到所有存在的钥匙和后创建补 “空” 键新的对象:

function mergeArrays(){ 
    var keys = {}; 
    //save all existed keys 
    for(var i=arguments.length;--i;){ 
     for(var j=arguments[i].length;--j;){ 
      for(var key in arguments[i][j]){ 
       keys[key] = true; 
      } 
     } 
    } 

    var res = []; 
    for(var i=arguments.length;--i;){ 
     for(var j=arguments[i].length;--j;){ 
      //set clone of object 
      var clone = JSON.parse(JSON.stringify(arguments[i][j])); 
      for(var key in keys){ 
       if(!(key in clone)){ 
        clone[key] = undefined; 
       } 
      } 
      res.push(clone); 
     } 
    } 

    return res; 
} 

https://jsfiddle.net/x3b0tk3g/

0

有可能解决一个较短的方式这包括所有步骤,包括确保有缺省属性undefined如果找不到。它还可以使用任意数量的输入数组,并且您可以指定所需的默认按键,如果它们尚未被现有对象中的按键所覆盖,那么您的需求就非常适合未来。

// merges the key/values of two objects 
function merge(a, b) { 
    var key; 
    if (a && b) { 
     for (key in b) { 
      if (b.hasOwnProperty(key)) { 
       a[key] = b[key]; 
      } 
     } 
    } 
    return a; 
} 

function concatenate() { 
    var result = []; 
    var args = arguments[0]; 
    for (var i = 0, l = args.length; i < l; i++) { 
     result = result.concat(args[i]); 
    } 
    return result; 
} 

// return a default object 
function getDefault() { 
    return { 
     id: undefined, 
     name: undefined, 
     data: undefined, 
     field: undefined 
    }; 
} 

// loop over the array and check the id. Add the id as a key to 
// a temporary pre-filled default object if the key 
// doesn't exist, otherwise merge the existing object and the 
// new object 
function createMergedArray(result) { 
    var temp = {}; 
    var out = []; 
    for (var i = 0, l = result.length; i < l; i++) { 
     var id = result[i].id; 
     if (!temp[id]) temp[id] = getDefault(); 
     merge(temp[id], result[i]); 
    } 

    // loop over the temporary object pushing the values 
    // into an output array, and return the array 
    for (var p in temp) { 
     out.push(temp[p]); 
    } 
    return out; 
} 

function mergeAll() { 

    // first concatenate the objects into a single array 
    // and then return the results of merging that array 
    return createMergedArray(concatenate(arguments)); 
} 

mergeAll(first, second, third); 

DEMO

0

小提琴:http://jsfiddle.net/bs20jvnj/2/

function getByProperty(arr, propName, propValue) { 
     for (var i = 0; i < arr.length; i++) { 
      if (arr[i][propName] == propValue) return arr[i]; 
     } 
    } 
var limit = first.length + second.length + third.length; 
var res = []; 
for (var i = 1; i < limit; i++) { 

    var x = $.extend({}, getByProperty(first, "id", i), getByProperty(second, "id", i), getByProperty(third, "id", i)); 
    console.log(x["id"]); 
    if (x["id"] === undefined) x["id"] = i; 
    res.push(x); 
} 

console.log(res);