5

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' )
});
1
  • 1
    Note that "filter out" means to remove unwanted items. You're not filtering out all objects which have risk P1. You're doing the opposite. Commented Apr 27, 2022 at 13:07

2 Answers 2

9

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.