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 ?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With