I have an array of objects. Each object in array has also an array. I would like to filter both of arrays, parent one and nested one. For example I have an array like:
[{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}]
When I apply filter, which returns objects in which has list elements which has value greater than 2 and also nested list itself is filtered. It should return
[{list:[3]},{list:[3,4]}]
Obj1 is not returned, because list inside it does not have any values which are greater 2, for Obj2 only list:[3] is returned and for Obj3 only list:[3,4] is returned
Is it possible to achieve without mutating original list?
The following code filters objects which has elements which are greater than 2
parent
.filter(obj => obj.list.some(el => el > 2))
What should I do next? If I apply a filter for nested array like
...
.filter(obj => obj.list.filter(el => el > 2))
Then as a result I get [[3],[3,4]]
but not object itself. Maybe anyone knows solution for that?
I have an array of objects. Each object in array has also an array. I would like to filter both of arrays, parent one and nested one. For example I have an array like:
[{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}]
When I apply filter, which returns objects in which has list elements which has value greater than 2 and also nested list itself is filtered. It should return
[{list:[3]},{list:[3,4]}]
Obj1 is not returned, because list inside it does not have any values which are greater 2, for Obj2 only list:[3] is returned and for Obj3 only list:[3,4] is returned
Is it possible to achieve without mutating original list?
The following code filters objects which has elements which are greater than 2
parent
.filter(obj => obj.list.some(el => el > 2))
What should I do next? If I apply a filter for nested array like
...
.filter(obj => obj.list.filter(el => el > 2))
Then as a result I get [[3],[3,4]]
but not object itself. Maybe anyone knows solution for that?
2 Answers
Reset to default 6I think I'd filter the sublist and then check its length:
var parent = [{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}];
parent = parent
.filter(obj => {
obj.list = obj.list.filter(el => el > 2);
return obj.list.length > 0; // Technically just `return obj.list.length;` would work; I prefer the clarity of the parison
});
console.log(parent);
And yes, the above could be done more concisely; I think the clarity suffers, but it's a judgement call:
var parent = [{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}];
parent = parent.filter(obj => (obj.list = obj.list.filter(el => el > 2)).length);
console.log(parent);
In addition to TJ Crowder's answer, I'd like to mention that you still getting mutated original list items.
It would be better to map initial array into new items with filtered list
property and then filter empty lists.
const parent = [{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}];
const filtered = parent
// filter nested lists first
.map(obj => {
// here we can use Object.assign to make shallow copy of obj, to preserve previous instance unchanged
return Object.assign({}, obj, {
list: obj.list.filter(el => el > 2)
})
})
// then omit all items with empty list
.filter(obj => obj.list.length > 0)
console.log(filtered);