Home > OS >  filter nested array of objects using javascript
filter nested array of objects using javascript

Time:04-28

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 );

  • Related