0

I have this data and need to apply all the filters using lodash. The final output is blank.

filters = [{'gender':'M'}, {'division':'police'}]

data = [{'name':'tom', 'gender':'M', 'division':'police'},
        {'name':'bob' , 'gender':'M', 'division':'police'},
        {'name':'dave' , 'gender':'F', 'division':'IT'},
        ]

data = _.filter(data, function(item){   
      _.forEach(filters, function(filter){     
            data_found = _.filter([item], filter)
            console.log('data_found - ', data_found)
        })        
      }) 

console.log(data)

https://jsfiddle.net/52k6170c/1/

user1050619
  • 19,822
  • 85
  • 237
  • 413
  • The predicate you give to `filter` never returns anything. Neither of them. EDIT: I'm actually confused what should be happening, since there is a foreach continually overwriting `data_found`...whatever that is – VLAZ Jan 17 '20 at 20:06
  • The final output should contain all records with gender-male and division-police – user1050619 Jan 17 '20 at 20:08

3 Answers3

1

You can combine your filters array to a single object and use that as your filter

combined = filters.reduce((acc,item) =>  ({...acc, ...item})) 
// combined is = {'gender':'M', 'division':'police'}

data = _.filter(data, combined)

if you feel like not using the rest operators, there is a lodash function that combines the array of objects into a single object

Prasanna
  • 4,125
  • 18
  • 41
0

You can use the _.filter method along with the _.every method to filter a collection based on another collection of predicates (I'm using arrow functions here). This example also assumes your filter objects only have a single key/value pair as in your example:

const filteredData = _.filter(data, item => {
  return _.every(filters, filter => {
    let filterKey = Object.keys(filter)[0]
    return item[filterKey] === filter[filterKey]
  })
})

A cleaner solution would be to combine your filters into a single object, and use the _.matches method to do a comparison:

const filter = { gender: 'M', division: 'police' }
const filteredData = _.filter(data, _.matches(filter))
djfdev
  • 5,747
  • 3
  • 19
  • 38
0

You can just combine both filter into one. Something like this

_.filter(data, function(item){
  if(item.gender === 'M' && item.division === 'police') return item;
})

This would give you all records with gender-male and division-police

0_0
  • 537
  • 1
  • 7
  • 20