Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter a javascript object array with variable parameters

I want to select the objects based on the properties of the objects, but not always the same properties. In other words:

arr = [
    { name: "joe",   age21: 1 },
    { name: "nick",  age21: 0 },
    { name: "blast", age21: 1 }
];

arr.filter(function(item) {
    return (item.name === "nick" && item.age21 === 1);
});

But sometimes I just want to filter on name for example:

arr.filter(function(item) {
    return (item.name === "nick");
});

What I want to do is generalize this so that the list of parameters can be passed to the function. I've come up with the following, but it's slow and I'm wondering if there is a better way:

filterParams = function(arr, params) {
    var new_array = arr.filter(function(item) {
        var select = 1
        for(obj in params) { //create the filter criteria based on varying set of parameters
            var select = select && params[obj] === item[obj];
        }
        return select;
    });
    return new_array;
}

Then you could call it with: filterParams(arr, {name: "nick", age21: 1});

or with: filterParams(arr, {name: "nick"});

and it would work either way.

In case you're wondering, I'm doing this because I have different data sets that I want to run through the same routine, so the filter properties need to be generalized so that I can filter on properties specific to each dataset.

Thanks!

like image 398
potterzot Avatar asked Jun 13 '13 23:06

potterzot


People also ask

How do you filter an object array based on attributes?

One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.

Can you use filter on an object in JavaScript?

JavaScript's Objects are not iterable like arrays or strings, so we can't make use of the filter() method directly on an Object . filter() allows us to iterate through an array and returns only the items of that array that fit certain criteria, into a new array.


1 Answers

Here's a functional approach that should work for any numbers of properties given the object:

function filter(arr, criteria) {
  return arr.filter(function(obj) {
    return Object.keys(criteria).every(function(c) {
      return obj[c] == criteria[c];
    });
  });
}

For example:

var arr = [
  { name: 'Steve', age: 18, color: 'red' },
  { name: 'Louis', age: 21, color: 'blue' }, //*
  { name: 'Mike', age: 20, color: 'green' },
  { name: 'Greg', age: 21, color: 'blue' }, //*
  { name: 'Josh', age: 18, color: 'red' }
];

console.log(filter(arr, { age: 21, color: 'blue' }));
//^ {age:21, color:'blue', name:'Louis}
//  {age:21, color:'blue', name:'Greg'}

Not sure about your performance issue, but this should be OK.

Edit: You could make this more powerful with regular expressions, something like this:

function filter(arr, criteria) {
  return arr.filter(function(obj) {
    return Object.keys(criteria).every(function(c) {
      return new RegExp(criteria[c]).test(obj[c]);
    });
  });
}

console.log(filter(arr, { age: /^2\d$/, color: /^(red|blue)$/ }));
//^ Louis, Greg                --^-- twenty-something
//                                               ----^---- red OR blue
like image 189
elclanrs Avatar answered Oct 06 '22 11:10

elclanrs