Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering array of objects with arrays based on nested value

I am trying to filter an array, based on some nested object. I prepared some Fiddle

Input array looks like this:

let arrayOfElements =      [         {            "name": "a",            "subElements":             [              {"surname": 1},              {"surname": 2}            ]         },         {            "name": "b",            "subElements":             [              {"surname": 3},              {"surname": 1}            ]         },         {            "name": "c",            "subElements":             [              {"surname": 2},              {"surname": 5}            ]         }     ]; 

I want the output for this case, to look like this:

let filteredArray =      [         {           "name": "a",           "subElements":            [             {"surname": 1}           ]         },         {           "name": "b",           "subElements":            [             {"surname": 1}           ]         } ]; 

I am using this formula to do that:

let filteredArray = arrayOfElements.filter((element) => element.subElements.some((subElement) => subElement.surname === 1)); 

Output is almost good, but it returns objects with all objects with surnames (better check that fiddle :D), instead of cutting them away. How can i improve the filtering ?

like image 342
bartosz.baczek Avatar asked Jul 14 '16 13:07

bartosz.baczek


People also ask

How do you filter an object array based on attributes?

One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.


2 Answers

This way you can go as deep as you want in an array and filter elements at any level,

arrayOfElements.map((element) => {   return {...element, subElements: element.subElements.filter((subElement) => subElement.surname === 1)} }) 

Spread operator will expand element and then filtered subElements will override the subElements in element.

like image 112
Nitesh Ranjan Avatar answered Sep 19 '22 08:09

Nitesh Ranjan


After you call filter, you need to pipe the results to map, like this:

let filteredArray = arrayOfElements   .filter((element) =>      element.subElements.some((subElement) => subElement.surname === 1))   .map(element => {     let newElt = Object.assign({}, element); // copies element     return newElt.subElements.filter(subElement => subElement.surname === '1');   }); 

I am assuming here that you don't want to manipulate the original array. So, I am using Object.assign.

like image 43
Andrew Eisenberg Avatar answered Sep 19 '22 08:09

Andrew Eisenberg