How can I filter by all the properties in an array of objects?

Viewed 267

Suppose I have an array like this:

  const people = [
    {
       "name":"pete22",
       "age":56
    },
    {
       "name":"sonya56",
       "age":22
    }
    ]

I can filter with lodash like this by name:

let result = people.filter(person =>_.includes(person.name,'56')
//{'name':'sonya56'}

What if I want to return all people with '56' in any property? So in the above example it would return both people? I am looking for a compact solution, maybe lodash?

6 Answers

You don't need Lodash to do this as JavaScript natively has support to do these kind of things. What you need to do is filter the people but also filter each value inside an entry, e.g.:

const people = [{
  "name": "pete22",
  "age": 56
}, {
  "name": "sonya56",
  "age": 22
}]

// Filter your 'people' JSON
const filteredPeople = people.filter(person => {
  // Filter each 'value' (property) inside each entry in 'people'
  return Object.values(person).filter(value => { 
    // Turn a value into a string and check if it includes the value '56'
    return value.toString().includes('56')
  })
})

console.log(filteredPeople)

What if I want to return all people with '56' in any property?

You need an array with all such properties with which you want to filter the input array.

var prop = [ "age", "size" ];

Now simply applies the filter in a loop

var valueToMatch = "56";
result = people;
prop.forEach( function( key ){
    if ( result.length ) { return true; } //if the result is already empty
    result = result.filter( function( peopleObj ){
       peopleObj[ key ] ==  valueToMatch;
    });
});

result is the output array filtered with all the properties given in prop array.

You could just use Array#filter with Object.values, Array#map with strings and check with Array#some and Array#includes.

const
    people = [{ name: "pete22", age: 56 }, { name: "sonya56", age: 22 }],
    filteredPeople = people.filter(person => Object
        .values(person)
        .map(String)
        .some(v => v.includes('56'))
    )

console.log(filteredPeople);

Stop using lodash for everything.

JavaScript:

let filtered = people.filter((e) => e.name === ‘foo’ && e.age === 23);

Keep in mind that && forces the two conditions and || says that only one of them must be true.

Extended solution for any number of properties:

var people = [
    { "name":"pete22", "age":56 }, {"name":"sonya56", "age":22 },
    { "name":"john33", "age":33 }, {name: "mike", "login":"56mike", "code": 10 }
],
result = people.filter(function(o){
   return Object.keys(o).some(function(k){ return String(o[k]).indexOf("56") !== -1; });
});
 
console.log(result);

We can filter again with values of Object

people.filter( hm=>Object.values(hm).filter( vl=>(vl+'').indexOf(56)>-1).length>0)

Related