2015-04-22 141 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);