admin管理员组

文章数量:1220776

I have an array of objects which I would like to filter using a contains/any method on a property using underscore.

For example, if I had the following variables:

var people = [
{
    name: 'Dave',
    age: 26
},
{
    name: 'Frank',
    age: 23
}];
var allowedAges = [20, 23, 24];

I would like to use underscore to end up with a result like:

 var allowedPeople = [];
 _.each(_.where(people, { age: _.any()}), function (person) {
            allowedPeople.push(person);
        });

And there may also be occasions where allowedAges is an array of objects and id want to use the contains/any on the people array using a property of the objects in allowedAges.

I have an array of objects which I would like to filter using a contains/any method on a property using underscore.

For example, if I had the following variables:

var people = [
{
    name: 'Dave',
    age: 26
},
{
    name: 'Frank',
    age: 23
}];
var allowedAges = [20, 23, 24];

I would like to use underscore to end up with a result like:

 var allowedPeople = [];
 _.each(_.where(people, { age: _.any()}), function (person) {
            allowedPeople.push(person);
        });

And there may also be occasions where allowedAges is an array of objects and id want to use the contains/any on the people array using a property of the objects in allowedAges.

Share Improve this question asked Mar 30, 2016 at 14:42 GrantGrant 931 gold badge1 silver badge8 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 12

The JS equivalent of contains is usually indexOf (and find in rare cases).

You can use the built-in Array.prototype.filter to do this like:

people.filter(function (person) {
  return allowedAges.indexOf(person.age) !== -1; // -1 means not present
});

or with underscore, using the same predicate:

_.filter(people, function (person) {
  return allowedAges.indexOf(person.age) !== -1; // -1 means not present
}

If you have access to ES6 collections or a polyfill for Set, you can replace the allowedAges array with a set (enforcing unique values) and simply use Set.prototype.has:

people.filter(person => allowedAges.has(person.age))

For the sake of completeness, here's an underscore solution that works with a mixed array of integers and objects containing an age property.

var allowedPeople = _.filter(people, (p) =>
  _.some(allowedAges, (a) => (a.age || a) === p.age)
);

Why not use vanilla js filter?

var people = [
  {
    name: 'Dave',
    age: 26
  },
  {
    name: 'Frank',
    age: 23
  }
];

var allowedAges = [20, 23, 24];

var allowedPeople = people.filter(function((person, i, arr) {
  return allowedAges.indexOf(person.age) !== -1;
});

This is a pure JS version:

var people = [{
  name: 'Dave',
  age: 26
}, {
  name: 'Frank',
  age: 23
}];
var allowedAges = [20, 23, 24];

function filterData(arr, key, searchList){
  var result = [];
  if(Array.isArray(searchList)){
    result = arr.filter(function(item){
      return (searchList.indexOf(item[key])>-1);
    });
  }
  else{
    result = arr.filter(function(item){
      return (searchList === item[key]);
    });
  }
  return result;
}

document.write("<pre>" + JSON.stringify(filterData(people,"age", allowedAges), 0, 4) + "</pre>")

本文标签: