2016-11-21 7 views
0

をマージ:ディープは、私は次のようにキー値を持つ2つの配列をマージする必要がネストされた配列

array1 = [ 
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]}, 
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]}] 

array2 = [ 
{id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
{id:"789", data:[{id:"456",data:"appended data"}]}, 
{id:"890", data:[{id:"456",data:"new data"}]}] 

merged = [ 
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"},{id:"456",data:"appended data"}]}, 
{id:"890", data:[{id:"456",data:"new data"}]}] 

のようなものを生成するために、私がしようとしてきましたこれはかなりの期間、このシナリオを満たす解決策を得ることができません。ほとんどのソリューションはid値に基づいているのではなく、ブラインドマージを行っています。 lodash mergeWithを使ってみましたが、必要な出力が得られませんでした。 Ramdaの解決法も許容されます。このリンクはあなたmerge two arraysに役立つことができ

+2

、あなたが –

+0

を試みたものを共有することのいずれかの可能性は、それはあなたを助けるでしたが... uはのため – Geeky

答えて

0

最後にこれは私のために働いていたものです。道を示すため@Geekyのおかげ:あなたはいくつかの時間のためにしようとしてきた

function mergeArrays(arr1, arr2) { 
    var arr3, arrIdx = []; 
    if (!arr1 || arr1.length ==0) return arr2 
    for (var i in arr1) { 
    var shared = false; 
    for (var j in arr2) 
     if (arr2[j].id == arr1[i].id) { 
     shared = true; 
     joined = _.mergeWith({},arr1[i],arr2[j], function (a,b) { 
      if (_.isArray(a)) return b.concat(a)}) 
     arr3.push(joined); 
     break; 
     } 
    if (!shared) { 
     arr3.push(arr1[i]); 
    } 
    } 
    for (var k in arr2) { 
    if (arrIdx[k] !=k) arr3.push(arr2[k]) 
    } 
    return arr3 

} 
0

おかげで、。

私は一意のプロパティを見つけて、その内容を変更していて、object2に存在しないプロパティも変更して、それをobject1にプッシュすると、set1とset2の間で共通のオブジェクトを見つけようとしました。

次のスニペットを確認してください。

var arr1 = [{ 
 
    id: "123", 
 
    data: [{ 
 
    id: "234", 
 
    data: "hello" 
 
    }, { 
 
    id: "345", 
 
    data: "there" 
 
    }, { 
 
    id: "xyz", 
 
    data: "yo" 
 
    }] 
 
}, { 
 
    id: "456", 
 
    data: [{ 
 
    id: "34", 
 
    data: "test" 
 
    }, { 
 
    id: "45", 
 
    data: "test2" 
 
    }, { 
 
    id: "yz", 
 
    data: "test3" 
 
    }] 
 
}, { 
 
    id: "789", 
 
    data: [{ 
 
    id: "23", 
 
    data: "aaa" 
 
    }, { 
 
    id: "34", 
 
    data: "bbb" 
 
    }, { 
 
    id: "xy", 
 
    data: "ccc" 
 
    }] 
 
}] 
 

 
var arr2 = [{ 
 
    id: "456", 
 
    data: [{ 
 
    id: "45", 
 
    data: "changed" 
 
    }, { 
 
    id: "yz", 
 
    data: "data" 
 
    }] 
 
}, { 
 
    id: "789", 
 
    data: [{ 
 
    id: "456", 
 
    data: "appended data" 
 
    }] 
 
}, { 
 
    id: "890", 
 
    data: [{ 
 
    id: "456", 
 
    data: "new data" 
 
    }] 
 
}] 
 
var arr3 = []; 
 
for (var i in arr1) { 
 
    var shared = false; 
 
    for (var j in arr2) 
 
    if (arr2[j].id == arr1[i].id) { 
 
     shared = true; 
 
     // arr1[i].data.concat(arr2[j].data); 
 
     var set1 = pushproperties(arr1[i].data, arr2[j].data); 
 
     arr1[i].data = set1; 
 
     arr3.push(arr1[i]); 
 
     break; 
 
    } 
 
    if (!shared) { 
 
    arr3.push(arr1[i]); 
 
    arr3.push(arr2[j]); 
 
    } 
 

 
} 
 

 
function pushproperties(set1, set2) { 
 
    var filtered = false; 
 
    set2.forEach(function(item) { 
 
    filtered = set1.every(function(element) { 
 
     return element.id != item.id; 
 

 
    }); 
 
    if (filtered) { 
 
     set1.push(item); 
 
    } 
 

 
    }); 
 

 
    set1.forEach(function(item) { 
 
    set2.forEach(function(element) { 
 
     if (item.id == element.id) { 
 
     item.data = element.data; 
 
     } 
 

 
    }); 
 

 

 
    }); 
 

 
    return set1; 
 

 
} 
 

 
console.log(arr3);

これは

+0

おかげで働いていたものを教えてくださいこの。これは私が必要とするものに近いと思われ、それはほとんど....働いています。いくつかの問題: –

+0

ありがとう。これは私が必要とするものに近いと思われ、それはほとんど....働いています。いくつかの問題があります:1.配列2に配列1の2番目の項目に一致する項目が1つしかない場合は、配列2のオブジェクトと結合されたオブジェクトの両方がarr 3にプッシュされます。
arr3.push (arr2 [j])を使用してこの問題を解決しますが、arr1に一致するものがarr2にない場合、arr2オブジェクトはarr3にプッシュされません。 –

0

この関数を再帰的Array.prototype.reduce()を使用してマージ2の配列に役立ちます願っています。同じidを持つアイテムが見つかった場合、配列であるdata propがあり、ロジックを使用してそれらをマージします。 dataが配列でない場合は、代わりに最後の項目によって上書きされます。

function mergeArraysDeep(arr1, arr2) { 
 
    var unique = arr1.concat(arr2).reduce(function(hash, item) { 
 
    var current = hash[item.id]; 
 
    
 
    if(!current) { 
 
     hash[item.id] = item; 
 
    } else if (Array.isArray(current.data)) { 
 
     current.data = mergeArraysDeep(current.data, item.data); 
 
    } else { 
 
     current.data = item.data; 
 
    } 
 

 
    return hash; 
 
    }, {}); 
 

 
    return Object.keys(unique).map(function(key) { 
 
    return unique[key]; 
 
    }); 
 
} 
 

 
var array1 = [ 
 
    {id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
 
    {id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]}, 
 
    {id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]} 
 
]; 
 

 
var array2 = [ 
 
    {id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
 
    {id:"789", data:[{id:"456",data:"appended data"}]}, 
 
    {id:"890", data:[{id:"456",data:"new data"}]} 
 
]; 
 

 
var result = mergeArraysDeep(array1, array2) 
 

 
console.log(result);

ES6 Mapを使用するバージョン、Map.prototype.values()、およびarray spread

const mergeArraysDeep = (arr1, arr2) => { 
 
    return [...arr1.concat(arr2).reduce((hash, item) => { 
 
    const current = hash.get(item.id); 
 
    
 
    if(!current) { 
 
     hash.set(item.id, item); 
 
    } else if (Array.isArray(current.data)) { 
 
     current.data = mergeArraysDeep(current.data, item.data); 
 
    } else { 
 
     current.data = item.data; 
 
    } 
 

 
    return hash; 
 
    }, new Map()).values()]; 
 
} 
 

 
const array1 = [ 
 
    {id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
 
    {id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]}, 
 
    {id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]} 
 
]; 
 

 
const array2 = [ 
 
    {id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
 
    {id:"789", data:[{id:"456",data:"appended data"}]}, 
 
    {id:"890", data:[{id:"456",data:"new data"}]} 
 
]; 
 

 
const result = mergeArraysDeep(array1, array2) 
 

 
console.log(result);

+0

ありがとうございます。私はデータのさまざまな組み合わせでこれを試しましたが、内側の配列を適切にマージすることができませんでした。 –

+0

答えにデモを試しましたか? –

+0

はい私は持っています。私の実際の世界のデータは異なるコンボがあり、あなたのソリューションがうまくいくと思っていましたが、テストデータのように内側の配列をマージしませんでした –

関連する問題