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?
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.
let filteredArray = arrayOfElements
.filter((element) =>
element.subElements.some((subElement) => subElement.surname == 1))
.map(element => {
return Object.assign({}, element, {subElements : element.subElements.filter(subElement => subElement.surname == 1)});
});
Try this solution:
data_filter = arrayOfElements.filter(function (element) {
return element.subElements.some( function (subElement) {
return subElement.surname === surname
});
});
Just improved the answers above
let elements = [ { "name": "a", "subElements": [ {"surname": 1}, {"surname": 2} ] }, { "name": "b", "subElements": [ {"surname": 3}, {"surname": 1} ] }, { "name": "c", "subElements": [ {"surname": 2}, {"surname": 5} ] } ]; var value = 1; var filteredArray = elements .filter(element => element.subElements .some(subElement => subElement.surname === value) ) .map(element => { let n = Object.assign({}, element, {'subElements': element.subElements.filter( subElement => subElement.surname === value )}) return n; }) console.log(filteredArray)
function display_message() { let arrayOfElements = [{ "name": "a", "subElements": [{ "surname": 1 }, { "surname": 2 }] }, { "name": "b", "subElements": [{ "surname": 3 }, { "surname": 1 }] }, { "name": "c", "subElements": [{ "surname": 2 }, { "surname": 5 }] }]; // console.log(arrayOfElements); var surname = 1; let filteredArray = arrayOfElements.filter((element) => element.subElements.some((subElement) => subElement.surname === surname)); for(var data in filteredArray){ filteredArray[data].subElements = {"surname": surname}; } console.log(filteredArray); }
<input type="button" onclick="display_message();" value="click"/>
You can make it generic as well:
subElements
value to filtered list. let arrayOfElements=[{name:"a",subElements:[{surname:1},{surname:2}]},{name:"b",subElements:[{surname:3},{surname:1}]},{name:"c",subElements:[{surname:2},{surname:5}]}]; let distinct_surnames = []; arrayOfElements.forEach(function(el) { el.subElements.forEach(function(s) { if (distinct_surnames.indexOf(s.surname) < 0) distinct_surnames.push(s.surname) }); }) let result = []; distinct_surnames.forEach(function(sn) { let inter = []; arrayOfElements.forEach(function(el) { let f = el.subElements.filter(function(sub) { return sub.surname === sn; }); if (f.length > 0) { let _tmp = Object.assign({}, el); _tmp.subElements = f; inter.push(_tmp); } }); result.push(inter); }) console.log(result)
Note: Arrow functions are used to keep the reference of this
. If you are not using this
inside function, you can use normal functions as well.
let filteredArray = arrayOfElements
.filter((element) =>
element.subElements.some((subElement) => subElement.surname === 1))
.map(element => {
let newElt = Object.assign({}, element); // copies element
newElt.subElements = newElt.subElements.filter(subElement => subElement.surName === '1');
return newElt;
});
is more correctly
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.