简体   繁体   中英

Lodash - Filter nested collection by array of prop value

Say the original collection is:

var data = [{
  id: 1,
  children: [{
    id: 2
  }, {
    id: 3
  }]
}, {
  id: 4,
  children: [{
    id: 5
  }]
}]

Want to filter it with this given values of id property:

var selectedIds = [1, 3, 4]

The results should be:

var result = [{
  id: 1,
  children: [{
    id: 3
  }]
}, {
  id: 4,
  children: []
}]

How to accomplish this using Lodash methods?

You'll need to recursively walk your collection (and each item's children). I don't believe lodash has a native way of implementing this. I wrote a function called matcher that takes the collection and selected ids, and returns items that match those ids, and passes the children in and does the same thing. I wasn't sure how to handle a situation where a parent isn't selected but the children are.... I just assumed you'd throw them all away.

Point is, you have a very particular structure (items and children that are items) that requires you to write a specific recursive function that knows how to walk that structure.

const matcher = (collection, selected) => _.reduce(collection, (result, item) => {

  if (selected.includes(item.id)) {
    result.push({
        id: item.id,
        children: matcher(item.children, selected)
    })
  }

  return result
}, [])

const result = matcher(data, selectedIds)

You can use map and filter together to apply filter on nested element,

_.map(data, elem => {
    elem.children = _.filter(elem.children, child => selectedIds.includes(child.id));
    return elem;
});

NOTE: Assuming the filter has to be applied only on children property.

To not modify the original data ,

_.map(data, elem => {
    let children = _.filter(elem.children, child => selectedIds.includes(child.id));
    return Object.assign({}, elem, {children});
});

You could check for id and take only children with wanted id.

 function getParts(array, ids) { return array.reduce((r, { id, children }) => r.concat(ids.includes(id) ? { id, children: getParts(children || [], ids) } : [] ), []); } var data = [{ id: 1, children: [{ id: 2 }, { id: 3 }] }, { id: 4, children: [{ id: 5 }] }]; console.log(getParts(data, [1, 3, 4])); console.log(getParts(data, [1, 3, 5])); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

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