过滤打字稿中对象内部的对象数组

时间:2020-10-28 03:13:42

标签: javascript angular typescript

我正在尝试使用内部的对象数组过滤对象。目前,我有这些数据。

 {
  tile: "test title",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-12345",
  schedules: [
    {
      id: 101,
      dateAssigned: "2019-10,-03",
      taskStatus: "On track"
    },
    {
      id: 102,
      dateAssigned: "2019-10,-03",
      taskStatus: "On track"
    }
  ]
},
{
  tile: "test title no. 2",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-54321",
  schedules: [
    {
      id: 101,
      dateAssigned: "2019-09,-03",
      taskStatus: "Overdue"
    }
  ]
},
{
  tile: "test title no. 3",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-99999",
  schedules: [
    {
      id: 103,
      dateAssigned: "2019-09,-03",
      taskStatus: "Open"
    }
  ]
}

我只想过滤“打开” “过期” 项目。

this.urgentRequests = this.urgentRequests.filter(a => {
   return a.schedules.find(s => s.taskStatus !== 'On track');
});

当前,它不起作用。是否可以同时进行过滤和查找?

我仍在获得“正在跟踪” 项目 enter image description here

预期输出仅获取过期和未清项目的数据。 但是现在它正在返回所有项目,包括“正在运行”

{
  tile: "test title no. 2",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-54321",
  schedules: [
    {
      id: 101,
      dateAssigned: "2019-09,-03",
      status: "Overdue"
    }
  ]
},
{
  tile: "test title no. 3",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-99999",
  schedules: [
    {
      id: 103,
      dateAssigned: "2019-09,-03",
      status: "Open"
    }
  ]
}

3 个答案:

答案 0 :(得分:2)

使用Array.prototype.reduce,您只能提取已过滤的项目。

const input = [{
  tile: "test title",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-12345",
  schedules: [
    {
      id: 101,
      dateAssigned: "2019-10,-03",
      status: "On track"
    },
    {
      id: 102,
      dateAssigned: "2019-10,-03",
      status: "On track"
    }
  ]
},
{
  tile: "test title no. 2",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-54321",
  schedules: [
    {
      id: 101,
      dateAssigned: "2019-09,-03",
      status: "Overdue"
    }
  ]
},
{
  tile: "test title no. 3",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-99999",
  schedules: [
    {
      id: 103,
      dateAssigned: "2019-09,-03",
      status: "Open"
    }
  ]
}];

const output = input.reduce((acc, cur) => {
  const schedules = cur.schedules.filter(({status}) => status === 'Open' || status === 'Overdue');
  if (schedules.length > 0) {
    acc.push({
      ...cur,
      schedules
    });
  }
  return acc;
}, []);
console.log(output);

答案 1 :(得分:1)

您在正确的轨道上,但是外部箭头功能缺少return,因此应使用some而不是find。如果箭头功能在身体周围有花括号,则需要使用return。我通过放下大括号来解决这个问题。另外,您写的是taskStatus而不是status

this.urgentRequests.filter(a =>
    a.schedules.some(s => s.status !== 'On track'))

答案 2 :(得分:1)

我认为您的代码几乎是正确的

// Your code
this.urgentRequests = this.urgentRequests.filter(a => {
  a.schedules.find(s => s.taskStatus !== 'On track');
});
  1. s.taskStatus更改为s.status。如果仔细观察,键名称为status
  2. 使用return语句。 filter需要一个返回布尔值作为输入的函数。就您而言,您的函数不返回任何内容,因此返回未定义(计算为false)。

因此,代码应如下所示:

this.urgentRequests = this.urgentRequests.filter(a => {
  return a.schedules.find(s => s.status !== 'On track');
});

编辑:我添加了代码段以确保一切正常。确实如此。您可以在下面查看。

const items = [{
  tile: "test title",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-12345",
  schedules: [
    {
      id: 101,
      dateAssigned: "2019-10,-03",
      status: "On track"
    },
    {
      id: 102,
      dateAssigned: "2019-10,-03",
      status: "On track"
    }
  ]
},
{
  tile: "test title no. 2",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-54321",
  schedules: [
    {
      id: 101,
      dateAssigned: "2019-09,-03",
      status: "Overdue"
    }
  ]
},
{
  tile: "test title no. 3",
  id: 1,
  createdBy: "johndoe@example.com",
  comments: "",
  taskId: "TK-99999",
  schedules: [
    {
      id: 103,
      dateAssigned: "2019-09,-03",
      status: "Open"
    }
  ]
}]

const targets = ["open", "overdue"];

const filterResult = items.filter(item => {
    return item.schedules.find(s => targets.includes(s.status.toLowerCase()))
})

console.log("I named the original array into 'items'.");
console.log("I add toLowerCase to make sure it wasn't typing issue.");
console.log("The results are: ", filterResult);
console.log("The result's schedules are: ", filterResult.map(a => a.schedules));
console.log(" No more 'On Track' right :) ");

注意:我正在使用几种新技术,但是想法仍然相同。