我想要有条件地加入两个数组:
aData = [ { id: 1, title: `bla`}, { id: 2, title: `la`}, { id: 3, title: `lala`} ]
bData = [ { id: 1, description: `bla`} ]
在第一种情况下,我希望只能获得具有合并属性的匹配结果(aData+bData
)
matchingIdsResult = [ { id: 1, title: `bla`, description: `bla` } ]
在第二种情况下,我希望获得不匹配的结果 - 只有来自aData
的对象,bData
中没有{ID>}
unmathingIdsResult = [ { id: 2, title: `la`}, { id: 3, title: `lala`} ]
我正在玩.map
和.reduce
并实现目前为止:
const data: any = aData.concat(bData).reduce((acc, x) => {
acc[x.id] = Object.assign(acc[x.id] || {}, x);
return acc;
}, {});
但是在这种情况下,到目前为止,我确实将所有aData
个对象与匹配的bData
属性合并,这实际上并不是我想要的。
答案 0 :(得分:1)
从id
按bData
创建Map。使用reduce迭代aData
。如果对象id
在bDataMap
中,则将组合对象推入第一个子数组。如果没有,到第二个。获取matchingIdsResult
和unmatchingIdsResult
destructuring的结果:reduce:
const aData = [{"id":1,"title":"bla"},{"id":2,"title":"la"},{"id":3,"title":"lala"}];
const bData = [{"id":1,"description":"bla"}];
const bDataMap = new Map(bData.map((o) => [o.id, o]));
const [matchingIdsResult, unmatchingIdsResult] = aData.reduce((r, o) => {
if(bDataMap.has(o.id)) r[0].push(Object.assign({}, o, bDataMap.get(o.id)));
else r[1].push(o);
return r;
}, [[], []]);
console.log(matchingIdsResult);
console.log(unmatchingIdsResult);

如果您想跳过bDataMap
的创建,可以使用Array.find()
。使用Map(n - aData.length,m - bData.length),复杂度将变为O(n * m)而不是o(n + m),但对于小数组,这可能是微不足道的:
const aData = [{"id":1,"title":"bla"},{"id":2,"title":"la"},{"id":3,"title":"lala"}];
const bData = [{"id":1,"description":"bla"}];
const [matchingIdsResult, unmatchingIdsResult] = aData.reduce((r, o) => {
const match = bData.find(({ id }) => id === o.id);
if(match) r[0].push(Object.assign({}, o, match));
else r[1].push(o);
return r;
}, [[], []]);
console.log(matchingIdsResult);
console.log(unmatchingIdsResult);

答案 1 :(得分:1)
您可以将第一个数组作为不匹配的起始值,并检查第二个数组并拆分匹配的对象或推送到不匹配的数组。
var aData = [{ id: 1, title: 'bla' }, { id: 2, title: 'la' }, { id: 3, title: 'lala' }],
bData = [{ id: 1, description: 'bla' }],
unmatching = aData,
matching = [];
bData.forEach(o => {
var index = unmatching.findIndex(({ id }) => o.id = id);
if (index === -1) {
unmatching.push(o);
} else {
matching.push(Object.assign({}, unmatching.splice(index, 1)[0], o));
}
});
console.log(matching);
console.log(unmatching);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:1)
如果id
存在与否,则创建一个不匹配和匹配检查的地图。
当你有两个单独的matched
和unmatched
的awway时,只需将matched
数组(基于ID
)与另一个包含的数组合并数据。
aData = [ { id: 1, title: `bla`}, { id: 2, title: `la`}, { id: 3, title: `lala`} ]
bData = [ { id: 1, description: `bla`} ];
var unmatched = [],
matched = [];
aData.every(x=> bData.map(e=> e.id).includes(x.id) ? matched.push(x) : unmatched.push(x))
matched = matched.map(x=> Object.assign(x, bData.find(e=> e.id ===x.id )))
console.log("Matched " , matched)
console.log("Un matched", unmatched)
.as-console-wrapper { max-height: 100% !important; top: 0; }