[英]Lodash - Merge objects of two arrays on condition
我有兩個對象數組。
arr1 = [
{
myName: 'Adam',
mySkill: 'CSS',
},
{
myName: 'Mutalib',
mySkill: 'JavaScript',
},
];
arr2 = [
{
myName: 'Adam',
myWeight: '112',
},
{
myName: 'Habib',
myWeight: '221',
},
];
我想要的結果是一個數組,其中包含第一個數組的對象,在第二個數組中具有匹配的屬性“myName”,以及相應的第二個數組對象的附加屬性。
result = [
{
myName = 'Adam'
mySkill = 'CSS'
myWeight = '112'
}
];
下面的解決方案組的級聯陣列( arr1
和arr2
通過) myName
,移除僅包含使用一個項目的所有組拒絕 ,最后利用地圖來合並所得到的數組。
var result = _(arr1)
.concat(arr2)
.groupBy('myName')
.reject({ length: 1 })
.map(_.spread(_.merge))
.value();
var arr1 = [ { myName: 'Adam', mySkill: 'CSS', }, { myName: 'Mutalib', mySkill: 'JavaScript', } ]; var arr2 = [ { myName: 'Adam', myWeight: '112', }, { myName: 'Habib', myWeight: '221', } ]; var result = _(arr1) .concat(arr2) .groupBy('myName') .reject({ length: 1 }) .map(_.spread(_.merge)) .value(); console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
另一種解決方案是使用intersectionWith獲取兩個數組之間的交集並同時分配缺失值。 注意使用cloneDeep來提升不變性。
var result = _.intersectionWith(_.cloneDeep(arr1), arr2, function(x, y) {
return x.myName === y.myName && _.assign(x, y);
});
var arr1 = [ { myName: 'Adam', mySkill: 'CSS', }, { myName: 'Mutalib', mySkill: 'JavaScript', } ]; var arr2 = [ { myName: 'Adam', myWeight: '112', }, { myName: 'Habib', myWeight: '221', } ]; var result = _.intersectionWith(_.cloneDeep(arr1), arr2, function(x, y) { return x.myName === y.myName && _.assign(x, y); }); console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
使用Array.prototype.forEach
和Object.assign
函數的替代本機 JS解決方案:
var arr1 = [ { myName: 'Adam', mySkill: 'CSS'}, { myName: 'Mutalib', mySkill: 'JavaScript'}, ], arr2 = [ { myName: 'Adam', myWeight: '112'}, { myName: 'Habib', myWeight: '221'} ], result = []; arr1.forEach(function (o) { arr2.forEach(function (c) { if (o.myName === c.myName) result.push(Object.assign({}, o, c)); }) }); console.log(result);
只有當myName
很常見時,才可以使用哈希表並推送對象。
var arr1 = [{ myName: 'Adam', mySkill: 'CSS' }, { myName: 'Mutalib', mySkill: 'JavaScript' }], arr2 = [{ myName: 'Adam', myWeight: '112' }, { myName: 'Habib', myWeight: '221' }], hash = Object.create(null), result = []; arr1.forEach(function (a) { hash[a.myName] = { myName: a.myName, mySkill: a.mySkill }; }); arr2.forEach(function (a) { if (hash[a.myName]) { hash[a.myName].myWeight = a.myWeight; result.push(hash[a.myName]); } }); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您還可以在Map對象的幫助下執行以下操作。
function mergeObjectsIfExists(p,a,b){ var m = a.reduce((m,o) => m.set(o[p],o), new Map()); return b.reduce((r,o) => m.has(o[p]) ? (r.push(m.set(o[p],Object.assign(m.get(o[p]),o)).get(o[p])),r) : r, []); } var arr1 = [{ myName: 'Adam', mySkill: 'CSS'}, { myName: 'Mutalib', mySkill: 'JavaScript'}, { myName: 'Jessuro', mySkill: 'Haskell'}], arr2 = [{ myName: 'Adam', myWeight: '112'}, { myName: 'Habib', myWeight: '221'}, { myName: 'Jessuro', myIQ: '150'}], result = mergeObjectsIfExists("myName",arr1,arr2); console.log(result);
如果使用lodash/fp
你可以組合函數來實現你想要的。 假設myName
是你的PK(或合並支點),你可以這樣做:
const mergeByName = compose(values, spread(merge), map(keyBy('myName')));
> mergeByName([arr1, arr2])
[ { myName: 'Adam', mySkill: 'CSS', myWeight: '112' },
{ myName: 'Mutalib', mySkill: 'JavaScript' },
{ myName: 'Habib', myWeight: '221' } ]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.