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 Set
s 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"