将一个对象数组与其他两个对象数组过滤时出现意外结果 [英] Unexpected result when filtering one object array against two other object arrays
问题描述
我正在尝试从数组 a中过滤出与数组 b和 c中的对象匹配的对象。这是 jsfiddle 的链接,以测试代码。
I'm trying to filter out objects from array "a" that match with objects in array "b" and "c". here is a link to jsfiddle to test the code.
这是我目前拥有的:
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"
}];
function sort(a, b, c) {
result = [];
console.log(result);
if (b !== null) {
result = a.filter(function(item) {
return !b.includes(item.uq_id);
})
}
if (c !== null) {
result = result.filter(function(item) {
return !c.includes(item.uq_id);
})
}
console.log(result);
}
sort(a, b, c);
我期望以下输出:
[{name="sofie", uq_id="abc2"}]
但是出于某些原因它会输出:
But for some reason it outputs:
[{name="sondre", uq_id="abc1"},
{name="sofie", uq_id="abc2"},
{name="casper", uq_id="abc3"},
{name="odin", uq_id="abc4"}]
有人知道我如何使它按预期工作吗?
Does anyone know how I can get this to work as I intended it?
推荐答案
如果目标是从名称为的
与 a
中过滤出条目 b
或 c
上的条目匹配,您不能使用包括
,除非 a
, b
和<$ c $中的条目c> c 指的是相同对象(不仅仅是等效的对象)。
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).
假设它们没有,则可以使用 some
来查找数组是否包含与名称
匹配的内容。您将要使用&
来查看 b
或<$ c $中都没有匹配项c> c :
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);
});
实时复制:
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"
}];
function filter(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);
});
如果 b
和 c
非常大(成千上万个条目,也许数百万个),其效率可能不足以证明创建 Set
s开头的名字:
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 = new Set([
...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.
实时复制:
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"
}];
function filter(a, b, c) {
const names = new Set([
...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));
这篇关于将一个对象数组与其他两个对象数组过滤时出现意外结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!