获取与迭代器函数匹配的集合的第一个元素

Posted

技术标签:

【中文标题】获取与迭代器函数匹配的集合的第一个元素【英文标题】:Get first element of a collection that matches iterator function 【发布时间】:2013-10-30 02:53:42 【问题描述】:

我想用_.filter 实现类似_.first 的东西,也就是说,拥有一组元素,我想获得第一个(如果存在)与真值测试(迭代器)匹配的元素。

例如,给定如下数组:

var arr = [a: 1, a: 5, a: 9, a: 11, a: 15]

我想获得第一个(也是唯一一个)与我的自定义函数匹配的元素:

_.filterFirst(arr, function(el)  return el.a > 10; ); // make it

到目前为止:

_.first(arr) == a:1
_.filter(arr, function(...)) == [a:11, a:15]

有没有比_.first(_.filter(arr, iterator))更好的干净解决方案?

【问题讨论】:

看一下查找功能underscorejs.org/#find 为什么不只是 _.filter(arr, iterator)[0] @levi 因为它消耗的 CPU 超出了应有的水平。 为什么不只是 _.filter(arr, iterator)[0] @RobertRavikumar 你听说过性能吗?还是算法复杂度? Here你去。顺便说一句,这个问题已经 5 岁了 【参考方案1】:

添加标准的 javascript Array.prototype.find 方法,因为只是旧的答案会让新手不了解:

const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found); 
// expected output: 12

示例来自上面链接的 MDN 页面。 还有一个 Array.prototype.findIndex 方法返回谓词产生 true 的位置的索引,而不是该索引的数组元素。

这些方法在 ES2015 中,即。 5 岁,几乎可以在人们使用的所有浏览器中使用,请参阅caniuse link。

【讨论】:

【参考方案2】:

_.find - 在lodash中: https://lodash.com/docs/4.17.10#find

var users = [
   'user': 'barney',  'age': 36, 'active': true ,
   'user': 'fred',    'age': 40, 'active': false ,
   'user': 'pebbles', 'age': 1,  'active': true 
];

_.find(users, function(o)  return o.age < 40; );
// => object for 'barney'

// The `_.matches` iteratee shorthand.
_.find(users,  'age': 1, 'active': true );
// => object for 'pebbles'

// The `_.matchesProperty` iteratee shorthand.
_.find(users, ['active', false]);
// => object for 'fred'

// The `_.property` iteratee shorthand.
_.find(users, 'active');
// => object for 'barney'

【讨论】:

【参考方案3】:

“_.find”是一个很好的解决方案。

另一种可能更快的解决方案是以这种方式使用“Array.prototype.every”:

var match;
arr.every(function(x)  if (x.a > 10)  match = x; return false; return true; )

【讨论】:

【参考方案4】:

你可以使用find:

查看列表中的每个值,返回第一个 通过真值测试(迭代器),如果没有值通过,则为 undefined 测试。该函数在找到可接受的元素后立即返回, 并且不会遍历整个列表。

用你的例子:

var g = _.find(arr, function (x)  return x.a > 10 )

查看主页:http://underscorejs.org

另一件需要注意的事情(这可能是您的问题)是 chain 将呼叫连接在一起的函数:

var g = _.chain(arr).filter(function (x)  return x.a > 10 ).first().value()

注意对 filter 和 `first' 的调用,它们可以相互跟随而没有任何嵌套。

【讨论】:

没错! _.find 是我需要的! ...或 Array.prototype.find(),但 IE 不支持。不过可以使用 polyfill。请注意,仅仅将 ES2015+ 翻译成 ES5 是不够的。

以上是关于获取与迭代器函数匹配的集合的第一个元素的主要内容,如果未能解决你的问题,请参考以下文章

3-22函数进阶——迭代器

迭代器与生成器

python迭代器与生成器

AngularJS操作DOM——angular.element

Python迭代器

python- 迭代器与生成器