Unexpected Result When Filtering One Object Array Against Two Other Object Arrays
Solution 1:
If the goal is to filter out entries from a whose name matches an entry on either b or c, you can't use includes unless the entries in a, b, and c refer to the same objects (not just equivalent ones).
Assuming they don't, you can use some to find out whether an array contains a match for a name. You'll want to use && to see that there's no match in either b or c:
const filtered = a.filter(entry => {
return !b.some(({name}) => entry.name === name) &&
!c.some(({name}) => entry.name === name);
});
Live Copy:
const a = [{
"name": "sondre",
"uq_id": "abc1"
}, {
"name": "sofie",
"uq_id": "abc2"
}, {
"name": "casper",
"uq_id": "abc3"
}, {
"name": "odin",
"uq_id": "abc4"
}];
const b = [{
"name": "sondre",
"uq_id": "abc1"
}, {
"name": "odin",
"uq_id": "abc4"
}];
const c = [{
"name": "casper",
"uq_id": "abc3"
}];
functionfilter(a, b, c) {
const filtered = a.filter(entry => {
return !b.some(({name}) => entry.name === name) &&
!c.some(({name}) => entry.name === name);
});
return filtered;
}
console.log(filter(a, b, c));That can also be expressed with every, whichever you prefer:
const filtered = a.filter(entry => {
return b.every(({name}) => entry.name !== name) &&
c.every(({name}) => entry.name !== name);
});
If b and c are really large (hundreds of thousands of entries, perhaps millions) that could be inefficient enough to justify creating Sets of names first:
const names = newSet([
...b.map(({name}) => name),
...c.map(({name}) => name)
]);
const filtered = a.filter(entry => {
return !names.has(entry.name);
});
Or you might just do that for preference or clarity.
Live Copy:
const a = [{
"name": "sondre",
"uq_id": "abc1"
}, {
"name": "sofie",
"uq_id": "abc2"
}, {
"name": "casper",
"uq_id": "abc3"
}, {
"name": "odin",
"uq_id": "abc4"
}];
const b = [{
"name": "sondre",
"uq_id": "abc1"
}, {
"name": "odin",
"uq_id": "abc4"
}];
const c = [{
"name": "casper",
"uq_id": "abc3"
}];
functionfilter(a, b, c) {
const names = newSet([
...b.map(({name}) => name),
...c.map(({name}) => name)
]);
const filtered = a.filter(entry => {
return !names.has(entry.name);
});
return filtered;
}
console.log(filter(a, b, c));Solution 2:
b and c are arrays of objects it only includes objects. You need to use some() on then to compare uq_id
const a = [{
"name": "sondre",
"uq_id": "abc1"
}, {
"name": "sofie",
"uq_id": "abc2"
}, {
"name": "casper",
"uq_id": "abc3"
}, {
"name": "odin",
"uq_id": "abc4"
}];
const b = [{
"name": "sondre",
"uq_id": "abc1"
}, {
"name": "odin",
"uq_id": "abc4"
}];
const c = [{
"name": "casper",
"uq_id": "abc3"
}];
sort(a, b, c);
functionsort(a, b, c) {
let result = [];
if (b !== null) {
result = a.filter(function(item) {
return !b.some(x => x.uq_id === item.uq_id);
})
}
if (c !== null) {
result = result.filter(function(item) {
return !c.some(x => x.uq_id === item.uq_id);
})
}
console.log(result);
}Solution 3:
Single filter is enough :
const a = [ { "name": "sondre", "uq_id": "abc1" },
{ "name": "sofie" , "uq_id": "abc2" },
{ "name": "casper", "uq_id": "abc3" },
{ "name": "odin" , "uq_id": "abc4" } ];
const b = [ { "name": "sondre", "uq_id": "abc1" },
{ "name": "odin" , "uq_id": "abc4" } ];
const c = [ { "name": "casper", "uq_id": "abc3" } ];
const result = a.filter(x => !b.some(y => x.uq_id === y.uq_id)
&& !c.some(y => x.uq_id === y.uq_id));
console.log(result);
Post a Comment for "Unexpected Result When Filtering One Object Array Against Two Other Object Arrays"