I am finding difficulty in filtering an nested array of object. Can someone please let me know where i am going wrong.
Here is the data and i want to filter out all objects which has risk 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",
}
]
}
]
I want the result as follows
[
{
"title": "QA",
"rows": [
{
"risk": "P1",
"Title": "Server down",
}
]
},
{
"title": "Prod",
"rows": [
{
"risk": "P1",
"Title": "Server is in hung state",
}
]
}
]
In order to achieve this, i tried this way but unable to get desired result. Can someone please let me know where i go wrong
data.forEach((element, index) => {
return element.rows.filter( x => x.risk === 'P1' )
});
CodePudding user response:
You should use map()
and 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; }
Explanation
You want to return one object for each of the original object values i.e. a 1:1
mapping so your primary operation is map()
.
Then you want to return the same object except that the property rows
should only contain the rows
with risk === "P1"
so you need to filter()
the rows and create a new object (you should treat objects as immutable) with that updated rows
property.
CodePudding user response:
First your original array needs an opening [
. Instead of using Array#forEach
use Array#map
instead. .forEach
does not return any result, but can allow you to modify the original array; .map
on the other hand creates a new array.
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 );
If your aim was to modify the original array, however, then make the following modification to your original code:
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 );