Ruby:没有块的select/find有什么用处吗?

Ruby:没有块的select/find有什么用处吗?,ruby,default,identity,lazy-evaluation,enumerable,Ruby,Default,Identity,Lazy Evaluation,Enumerable,我有一个懒惰的求值,我想要一个映射操作得到的第一个真实结果,我再次发现自己在写。在表达式的末尾找到{e} 这里有一个简单的例子;当然,阵列和地图块在我的现实生活中是不同的: [nil, 2, 3, 4].lazy.map{ |e| e }.find { |e| e } 当我不得不将块{| e | e}添加到select或find中时,我总是有点惊讶/失望,特别是如果它是一个懒惰的求值,因为这两者(冗余地)在默认情况下似乎都是身份函数: > [nil, 2, 3, 4].find { |e

我有一个懒惰的求值,我想要一个映射操作得到的第一个真实结果,我再次发现自己在写。在表达式的末尾找到{e}

这里有一个简单的例子;当然,阵列和地图块在我的现实生活中是不同的:

[nil, 2, 3, 4].lazy.map{ |e| e }.find { |e| e }
当我不得不将块{| e | e}添加到select或find中时,我总是有点惊讶/失望,特别是如果它是一个懒惰的求值,因为这两者(冗余地)在默认情况下似乎都是身份函数:

> [nil, 2, 3, 4].find { |e| e } 
 => 2
> [nil, 2, 3, 4].find
 => #<Enumerator: [nil, 2, 3, 4]:find>
> [nil, 2, 3, 4].find.map { |e| e }
 => [nil, 2, 3, 4] 
与select类似,但这对lazy更没有帮助:

> [nil, 2, 3, 4].select
 => #<Enumerator: [nil, 2, 3, 4]:select>
> [nil, 2, 3, 4].select { |e| e }
 => [2, 3, 4]
> [nil, 2, 3, 4].select.lazy.force   # doing it wrong looks functional!
 => [nil, 2, 3, 4] 
> [nil, 2, 3, 4].lazy.select { |e| e }.force
 => [2, 3, 4]
> [nil, 2, 3, 4].lazy.select.force   # same without .force
ArgumentError: tried to call lazy select without a block

这些都是明显的身份和错误!有用,或者只是在未来版本的Ruby中提供更好的默认值的机会?

首先,一个小评论。如果您发现自己在键入{e},可以改用&:本身

在这种情况下,没有块的可枚举方法通常会多次返回枚举数。您可以使用它来链接枚举器方法。例如,考虑:

[1, 2, 3].map.with_index  { |n, i| n + i } # => [1, 3, 5]
[1, 2, 3].each.with_index { |n, i| n + i } # => [1, 2, 3]

[1, 2, 3].select.with_index { |n, i| (n + 2 * i).even? } # => [2]

很好,但是由于OP特别要求选择,您可以使用select.Mm显示一个示例,感谢您的快速响应。select.with_index{| |,i | i>2}确实有意义,但它不适用于lazy,这看起来有点像一个漏洞。谢谢你提到&:它本身——有趣而且可能更有效,但对我的大脑来说没有{e}那么清楚@黄鼠狼,既然你指出了这一点——这很奇怪。您仍然可以使用[1,2,3].lazy.with_index.select{:whatever}执行此操作。不同的是,您也可以在结果中获得索引,但wtf、Ruby除外。xdselect.with_index{| |,i | i>2}将只是DROP3,直到我链接或应用块do[1,2,3]。每个和[1,2,3]。选择是否返回基本相同的枚举数?与应用枚举器方法时表现稍有不同的类似cycle的情况相反。不带块的cycle返回无限循环的枚举器,即next可以无限期应用,因此与其他枚举器略有不同。
[1, 2, 3].map.with_index  { |n, i| n + i } # => [1, 3, 5]
[1, 2, 3].each.with_index { |n, i| n + i } # => [1, 2, 3]

[1, 2, 3].select.with_index { |n, i| (n + 2 * i).even? } # => [2]