JavaScript根据另一个对象数组的属性过滤对象数组

时间:2018-01-02 19:08:27

标签: javascript

我有2 array of objects

Tasks
[{
 name: "test",
 type: "one"
},
{
 name: "test2",
 type: 'two'
}]

活动

[{
 name: "test",
 type: "one"
},
{
 name: "test2",
 type: 'two'
},
{
 name: "test3",
 type: "three"
 }]

如何通过tasks数组的属性过滤活动数组?我想要这个结果。

活动

[{
 name: "test",
 type: "one"
},
{
 name: "test2",
 type: 'two'
}]

我尝试过使用.filter(),但是返回一个空集合。

let tests = activities.filter(x => tasks.includes(x.type));

如何在Javascript中实现这一目标?

2 个答案:

答案 0 :(得分:6)

filter是正确的工具,但includes不是。 tasks中的条目是对象,而不是字符串;它们都不会匹配tests中的任何类型。

相反,简单版本使用some来查看tasks中的任何条目是否与正在测试的活动的类型相匹配:

let tests = activities.filter(a => tasks.some(t => t.type == a.type));

直播示例:

const tasks = [
  {
    name: "test",
    type: "one"
  },
  {
    name: "test2",
    type: 'two'
  }
];
const activities = [
  {
    name: "test",
    type: "one"
  },
  {
    name: "test2",
    type: 'two'
  },
  {
    name: "test3",
    type: "three"
  }
];
 
let tests = activities.filter(a => tasks.some(t => t.type == a.type));
console.log(tests);
.as-console-wrapper {
  max-height: 100% !important;
}

当然,这意味着至少部分地为tasks中的每个条目重新遍历activities。对于你所展示的例子,这绝对没问题;如果tasks长达数十万个条目,或者这是在一个紧密循环中完成的,而不是那么多。 : - )

在这种情况下,您可以提前从tasks给自己一组已知类型,然后只针对该集进行测试:

const knownTypes = new Set();
for (const task of tasks) {
    knownTypes.add(task.type);
}
let tests = activities.filter(a => knownTypes.has(a.type));

直播示例:

const tasks = [
  {
    name: "test",
    type: "one"
  },
  {
    name: "test2",
    type: 'two'
  }
];
const activities = [
  {
    name: "test",
    type: "one"
  },
  {
    name: "test2",
    type: 'two'
  },
  {
    name: "test3",
    type: "three"
  }
];
 
const knownTypes = new Set();
for (const task of tasks) {
    knownTypes.add(task.type);
}
let tests = activities.filter(a => knownTypes.has(a.type));
console.log(tests);
.as-console-wrapper {
  max-height: 100% !important;
}

或者,代替Set,您也可以使用knownTypes的对象,通过Object.create(null)通过Object.prototype创建它,您的任何类型都可能是同名的作为const knownTypes = Object.create(null); for (const task of tasks) { knownTypes[task.type] = true; } let tests = activities.filter(a => knownTypes[a.type]); 上的财产:

const tasks = [
  {
    name: "test",
    type: "one"
  },
  {
    name: "test2",
    type: 'two'
  }
];
const activities = [
  {
    name: "test",
    type: "one"
  },
  {
    name: "test2",
    type: 'two'
  },
  {
    name: "test3",
    type: "three"
  }
];
 
const knownTypes = Object.create(null);
for (const task of tasks) {
    knownTypes[task.type] = true;
}
let tests = activities.filter(a => knownTypes[a.type]);
console.log(tests);

直播示例:

.as-console-wrapper {
  max-height: 100% !important;
}
WITH

答案 1 :(得分:3)

几乎就在那里。尝试使用.some数组方法检查项目是否存在,因为includes不适用于嵌套属性。



const tasks = [{
 name: "test",
 type: "one"
},
{
 name: "test2",
 type: 'two'
}]

const activities = [{
 name: "test",
 type: "one"
},
{
 name: "test2",
 type: 'two'
},
{
 name: "test3",
 type: "three"
 }]
 
let tests = activities.filter(x => tasks.some(t => t.type === x.type));
console.log(tests)