使用JavaScript过滤嵌套对象数组

3

我在过滤嵌套数组对象时遇到了困难。请问有人能告诉我哪里出了问题。

这是数据,我想筛选出所有风险为P1的对象。

    {
        "title": "QA",
        "rows": [
            {
                "risk": "P1",
                "Title": "Server down",
            },
            {
                "risk": "P3",
                "Title": "Permission issue",
            }
        ]
    }, 
    {
        "title": "Prod",
        "rows": [
            {
                "risk": "P5",
                "Title": "Console log errors fix",
            },
            {
                "risk": "P1",
                "Title": "Server is in hung state",
            }
        ]
    }
]

我想要以下结果。
[
    {
        "title": "QA",
        "rows": [
            {
                "risk": "P1",
                "Title": "Server down",
            }
        ]
    }, 
    {
        "title": "Prod",
        "rows": [
            {
                "risk": "P1",
                "Title": "Server is in hung state",
            }
        ]
    }
]

为了实现这个目标,我尝试了这种方法,但无法得到期望的结果。请问有人能告诉我哪里出了问题吗?
data.forEach((element, index) => {
  return element.rows.filter( x => x.risk === 'P1' )
});

1
请注意,“filter out”意味着删除不需要的项目。您并没有过滤掉所有具有风险P1的对象。您正在做相反的事情。 - jarmod
2个回答

8

你应该使用map()filter()

const input = [
  {
    title: "QA",
    rows: [
      {
        risk: "P1",
        Title: "Server down",
      },
      {
        risk: "P3",
        Title: "Permission issue",
      },
    ],
  },
  {
    title: "Prod",
    rows: [
      {
        risk: "P5",
        Title: "Console log errors fix",
      },
      {
        risk: "P1",
        Title: "Server is in hung state",
      },
    ],
  },
];

const output = input.map((obj) => ({
  ...obj,
  rows: obj.rows.filter((row) => row.risk === "P1"),
}));

console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

解释

您希望针对原始对象值返回一个对象,即1:1映射,因此您的主要操作是使用map()函数。

然后,您想要返回相同的对象,但是属性rows应仅包含risk === "P1"rows,因此您需要使用filter()函数来过滤行并创建一个新对象(您应该将对象视为不可变对象),该对象具有更新的rows属性。


3

首先,您的原始数组需要一个开放性[。不要使用Array#forEach,而是使用Array#map代替。 .forEach不返回任何结果,但可以让您修改原始数组; 另一方面,.map创建一个新数组。

const input = [{ "title": "QA", "rows": [ { "risk": "P1", "Title": "Server down", }, { "risk": "P3", "Title": "Permission issue", } ] }, { "title": "Prod", "rows": [ { "risk": "P5", "Title": "Console log errors fix", }, { "risk": "P1", "Title": "Server is in hung state", } ] } ],
     filter = "P1",
     
     output = input.map(
         ({rows,...rest}) => 
         ({...rest, rows: rows.filter(({risk}) => risk === filter)})
     );
     
console.log( output );

如果您的目标是修改原始数组,则请对原始代码进行以下修改:

const input = [{ "title": "QA", "rows": [ { "risk": "P1", "Title": "Server down", }, { "risk": "P3", "Title": "Permission issue", } ] }, { "title": "Prod", "rows": [ { "risk": "P5", "Title": "Console log errors fix", }, { "risk": "P1", "Title": "Server is in hung state", } ] } ],
     filter = "P1";
     
     input.forEach((element,index) => {
         input[index] = {...element, rows: element.rows.filter( x => x.risk === filter )}
    });
     
console.log( input );


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接