我尝试获取数组的每个对象并将其与另一个数组的对象进行比较。如果它们匹配,则从第二个数组中删除该对象。
奇怪的是,如果一个对象在数组中找到两次,则该对象不会被过滤。
我想将新数据
与现有
进行比较。如果 newdata
的对象具有相同的 id 和 cat,则它将不会出现在 new 数组中。
现有
是
var existing = [{
name: "John",
values_: {
id: 5,
cat: true
}
},
{name: "Jake",
values_: {
id: 3,
cat: true
}
},
{
name: "Alice",
values_: {
id: 2,
cat: false
}
}
];
newdata
是
var newdata = [{
name: "Mike",
properties: {
id: 1,
cat: true
}
},
{name: "Jake",
properties: {
id: 3,
cat: true
}
},
{name: "Jake",
properties: {
id: 3,
cat: true
}
},
{
name: "Alice",
properties: {
id: 2,
cat: false
}
}
];
我的过滤器是
existing.forEach((existingitem, existingindex, existingfeatures) => {
newdata2 = newdata.filter(item => (
existingitem.values_.id != item.properties.id &&
existingitem.values_.cat != item.properties.cat
));
});
console.log('newdata2 - ',newdata2);
逻辑是 newdata2
只有 Mike
。问题是我可以看到 Jake
两次。 Jake
不应该在那里,它已经在现有
中。
如果我像这样编辑newdata
(没有 double )
var newdata = [{
name: "Mike",
properties: {
id: 1,
cat: true
}
},
{name: "Jake",
properties: {
id: 3,
cat: true
}
} ,
{
name: "Alice",
properties: {
id: 2,
cat: false
}
}
];
我仍然可以在 newdata2
中看到 Jake
。但为什么?
请帮我解决这个问题。是我的过滤器还是 filter
的工作方式?根据标准,我最后应该只得到 Mike
。请指教。
谢谢
var existing = [{
name: "John",
values_: {
id: 5,
cat: true
}
},
{name: "Jake",
values_: {
id: 3,
cat: true
}
},
{
name: "Alice",
values_: {
id: 2,
cat: false
}
}
];
var newdata = [{
name: "Mike",
properties: {
id: 1,
cat: true
}
},
{name: "Jake",
properties: {
id: 3,
cat: true
}
},
{name: "Jake",
properties: {
id: 3,
cat: true
}
},
{
name: "Alice",
properties: {
id: 2,
cat: false
}
}
];
existing.forEach((existingitem, existingindex, existingfeatures) => {
newdata2 = newdata.filter(item => (
existingitem.values_.id != item.properties.id &&
existingitem.values_.cat != item.properties.cat
));
});
console.log('newdata2 - ',newdata2);
最佳答案
...考虑基于 filter
(外部)和 every
(内部)的方法,而不是 forEach
和 filter
- 也许这会让我们更容易思考正确的实现。
var existingItemList = [{ name: "John", values_: { id: 5, cat: true }}, { name: "Jake", values_: { id: 3, cat: true }}, { name: "Alice", values_: { id: 2, cat: false }}];
var newItemList = [{ name: "Mike", properties: { id: 1, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Alice", properties: { id: 2, cat: false }}];
var itemList = newItemList.filter(function (newItem) { // filter `newItem` only
return existingItemList.every(function (existingItem) { // if it does not exist
return ( // in `existingItemList`.
//(newItem.name !== existingItem.name) &&
(newItem.properties.id !== existingItem.values_.id)
);
});
});
console.log('itemList : ', itemList);
.as-console-wrapper { max-height: 100%!important; top: 0; }
编辑
跟进,引用我的这条评论...
your comparison condition just does not fit what you are really searching/looking for.
如果仍然假设 OP 仅在新项目尚不存在于要与之比较的另一个列表中时才过滤新项目......
...必须编写一个匹配器函数来一次性映射和比较项目字段。
然后,必须以某种方式使用此比较器/匹配器,使其仅过滤不等于任何其他已存在项目的非常新的项目。
这可以通过对上面的前一种方法稍加改变来实现......
function doesExistingItemMatchBoundNewItem(existingItem) {
var newItem = this;
return (
(newItem.properties.id === existingItem.values_.id)
&& (newItem.properties.cat === existingItem.values_.cat)
);
}
var existingItemList = [{ name: "John", values_: { id: 5, cat: true }}, { name: "Jake", values_: { id: 3, cat: true }}, { name: "Alice", values_: { id: 2, cat: false }}];
var newItemList = [{ name: "Mike", properties: { id: 1, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Alice", properties: { id: 2, cat: false }}];
var itemList = newItemList.filter(function (newItem) {
return !existingItemList.some(doesExistingItemMatchBoundNewItem.bind(newItem));
});
console.log('itemList : ', itemList);
.as-console-wrapper { max-height: 100%!important; top: 0; }
关于javascript - 当找到两个对象时,forEach 内部的过滤器无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53632644/