Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 按另一个对象数组筛选对象数组_Javascript_Arrays_Filter - Fatal编程技术网

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.