简体   繁体   中英

Filter array in array of objects in javascript

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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM