使用Underscore.js根据属性使用“包含”来过滤对象数组

7
我是一位能够翻译中文的助手。以下是有关IT技术方面需要翻译的内容。您需要使用Underscore对一个对象数组进行过滤,并使用包含/任何方法过滤属性。举个例子,如果我有以下变量:
var people = [
{
    name: 'Dave',
    age: 26
},
{
    name: 'Frank',
    age: 23
}];
var allowedAges = [20, 23, 24];

我想使用下划线来得到以下结果:
 var allowedPeople = [];
 _.each(_.where(people, { age: _.any()}), function (person) {
            allowedPeople.push(person);
        });

有时候,allowedAges 可能是一个对象数组,而我需要使用 allowedAges 对象中的属性,在 people 数组上使用 contains/any。

4个回答

12

在JavaScript中,contains的等价方法通常是indexOf(在极少数情况下可以使用find)。

您可以使用内置的Array.prototype.filter 来实现此功能,例如:

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

或者使用下划线,使用相同的谓词:

_.filter(people, function (person) {
  return allowedAges.indexOf(person.age) !== -1; // -1 means not present
}
如果您可以访问ES6集合或Set的polyfill,您可以将allowedAges数组替换为一个集合(强制唯一值),并简单地使用Set.prototype.has
people.filter(person => allowedAges.has(person.age))

1
OP要求一个下划线解决方案,而不是一个普通的js解决方案。我不能给你点踩,因为你已经按照问题所问回答了,并且纯js解决方案可以被视为额外信息,但既然OP明确提出了有关underscore的问题,为什么纯js的东西还是必要的呢?另外,为什么你的答案中“native”部分排在第一位? - Software Engineer
2
@EngineerDollery说“我想使用下划线”并不意味着他必须使用下划线,没有任何地方声明“必须使用下划线来完成此任务”。 - George
@EngineerDollery 为了推广内置方法。很多人都忘记了它们,但现在大多数浏览器都使用它们(underscore主要是在数组拥有函数方法之前的一个polyfill)。由于OP问到了underscore,等效的解决方案也在那里以备不时之需。 - ssube

3
为了完整起见,这里提供一个下划线方案,适用于混合整数和包含 age 属性的对象数组。
var allowedPeople = _.filter(people, (p) =>
  _.some(allowedAges, (a) => (a.age || a) === p.age)
);

我曾两次搜索并找到了这篇帖子,但每次前两个答案都返回了空数组,不过 Aldehir 的这个答案两次都起作用。 - Bitfool

0

这是一个纯JS版本:

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>")


1
OP要求下划线解决方案,而不是普通的js解决方案。 - Software Engineer

0

为什么不使用原生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;
});

1
OP要求下划线解决方案,而不是普通的js解决方案。 - Software Engineer
1
@EngineerDollery,很有可能OP不知道还有非下划线的解决方案。 - Matthew Herbst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接