Javascript 按另一个对象数组筛选对象数组
我想用另一个对象数组过滤对象数组 我有两个这样的对象数组:Javascript 按另一个对象数组筛选对象数组,javascript,arrays,filter,Javascript,Arrays,Filter,我想用另一个对象数组过滤对象数组 我有两个这样的对象数组: const array = [ { id: 1, name: 'a1', sub: { id: 6, name: 'a1 sub' } }, { id: 2, name: 'a2', sub: null }, { id: 3, name: 'a3', sub: { id: 8, name: 'a3 sub' } }, { id: 4, name: 'a4', sub: null }, { id:
const array = [
{ id: 1, name: 'a1', sub: { id: 6, name: 'a1 sub' } },
{ id: 2, name: 'a2', sub: null },
{ id: 3, name: 'a3', sub: { id: 8, name: 'a3 sub' } },
{ id: 4, name: 'a4', sub: null },
{ id: 5, name: 'a5', sub: { id: 10, name: 'a5 sub' } },
];
const anotherArray = [
{ id: 1, name: 'a1', sub: { id: 6, name: 'a1 sub' } },
{ id: 2, name: 'a2', sub: null },
{ id: 5, name: 'a5', sub: { id: 10, name: 'a5 sub' } },
];
我希望通过另一个数组过滤array
,并返回另一个数组中不存在且具有子数组的项
因此,我期望的输出是:
[ { id: 3, name: 'a3', sub: { id: 8, name: 'a3 sub' } ]
注意:我已经用for循环完成了这项工作,但是它工作得太慢了。我想使用数组过滤方法来实现这一点
我在for循环中使用的代码:
for (let i = 0; i < array.length; i += 1) {
let exist = false;
const item = array[i];
for (let j = 0; j < anotherArray.length; j += 1) {
const anotherItem = anotherArray[j];
if (item.id === anotherItem.id) {
exist = true;
}
}
if (item.sub && !exist) {
this.newArray.push({
text: `${item.sub.name} / ${item.name}`,
value: item.id,
});
}
}
for(设i=0;i
就像Felix提到的那样,数组#过滤器
的工作速度不会比原生for循环快,但是如果您真的希望将其作为一种功能方式,这里有一个可能的解决方案:
const数组=[
{id:1,名称:'a1',sub:{id:6,名称:'a1 sub'},
{id:2,名称:'a2',sub:null},
{id:3,名称:'a3',sub:{id:8,名称:'a3 sub'},
{id:4,名称:'a4',sub:null},
{id:5,名称:'a5',sub:{id:10,名称:'a5 sub'},
];
常数另一个数组=[
{id:1,名称:'a1',sub:{id:6,名称:'a1 sub'},
{id:2,名称:'a2',sub:null},
{id:5,名称:'a5',sub:{id:10,名称:'a5 sub'},
];
常量r=array.filter((elem)=>!另一个array.find({id})=>elem.id==id)和&elem.sub);
控制台日志(r)代码>您可以使用JSON.stringify来比较这两个对象。最好编写一个递归比较对象上所有属性的函数
const数组=[
{id:1,名称:'a1',sub:{id:6,名称:'a1 sub'},
{id:2,名称:'a2',sub:null},
{id:3,名称:'a3',sub:{id:8,名称:'a3 sub'},
{id:4,名称:'a4',sub:null},
{id:5,名称:'a5',sub:{id:10,名称:'a5 sub'},
];
常数另一个数组=[
{id:1,名称:'a1',sub:{id:6,名称:'a1 sub'},
{id:2,名称:'a2',sub:null},
{id:5,名称:'a5',sub:{id:10,名称:'a5 sub'},
];
常量notIn=(array1,array2)=>array1.filter(item1=>{
const item1Str=JSON.stringify(item1);
return!array2.find(item2=>item1Str==JSON.stringify(item2))
}
);
log(notIn(数组,另一个数组))代码>好的,让我们一步一步地解决这个问题
为了简化这个过程,我们假设两个元素都具有相同的id
,则可以认为它们相等
我将使用的第一种方法是迭代第一个数组,对于每个元素,迭代第二个数组以检查上面定义的条件
const A = [ /* ... */]
const B = [ /* ... */]
A.filter(el => {
let existsInB = !!B.find(e => {
return e.id === el.id
}
return existsInB && !!B.sub
})
如果我们确定A和B中的元素在具有相同ID时实际上是相同的,那么我们可以跳过所有A元素,而不使用sub
属性来执行它
A.filter(el => {
if (!el.sub) return false
let existsInB = !!B.find(e => {
return e.id === el.id
}
return existsInB
})
现在,如果我们的数组比这个大,这意味着我们要浪费很多时间寻找B中的元素。
通常,在这些情况下,我将查找的数组转换为一个映射,如下所示
var BMap = {}
B.forEach(el => {
BMap[el.id] = el
})
A.filter(el => {
if (!el.sub) return false
return !!BMap[el.id]
})
通过这种方式,您在开始创建地图时“浪费”了一点时间,但这样您可以更快地找到元素
从这里可能会有更多的优化,但我认为这对于这个问题来说已经足够了,您可以使用,因为后者将返回布尔值,而不是如下所示的元素:
const a1=[{id:1,名称:'a1',sub:{id:6,名称:'a1 sub'},{id:2,名称:'a2',sub:null},{id:3,名称:'a3',sub:{id:8,名称:'a3 sub'},{id:4,名称:'a4',sub sub null},{id:5,名称:'a5',sub id:10,名称:'a5 sub sub;
常量a2=[{id:1,名称:'a1',sub:{id:6,名称:'a1 sub'}},{id:2,名称:'a2',sub:null},{id:5,名称:'a5',sub:{id:10,名称:'a5 sub'},];
const result=a1.filter({id,sub})=>!a2.some(x=>x.id==id)和&sub)
console.log(result)
优化版本:不需要每次都搜索元素,创建一个字典并在O(1)中搜索##
const数组=[{
id:1,
名称:“a1”,
分:{
id:6,
名称:“a1 sub”
}
},
{
id:2,
名称:“a2”,
sub:null
},
{
id:3,
名称:“a3”,
分:{
id:8,
名称:“a3分包商”
}
},
{
id:4,
名称:“a4”,
sub:null
},
{
id:5,
名称:“a5”,
分:{
id:10,
名称:“a5分包商”
}
},
];
常数另一个数组=[{
id:1,
名称:“a1”,
分:{
id:6,
名称:“a1 sub”
}
},
{
id:2,
名称:“a2”,
sub:null
},
{
id:5,
名称:“a5”,
分:{
id:10,
名称:“a5分包商”
}
},
];
const dict=另一个数组。reduce((acc,curr)=>{
常数{id}=curr;
acc[id]=当前值;
返回acc;
}, {});
常量结果=数组.过滤器((obj)=>{
const search=dict[obj.id];
如果(!search&&obj.sub)返回true;
返回false;
});
控制台日志(结果)
Array#filter
也会在数组上迭代,只是在内部。天真地将for
循环转换为.filter
可能不会加快代码的速度。请张贴你的代码。可能的重复哦,谢谢你的作品伟大!我有300多个项目在数组中,这就是为什么我认为循环工作缓慢谢谢你,这正是我所寻找的稍加修改。我有两个数组,需要在第三个数组中求出它们的差。我刚刚删除了&&子部分+1.