Enumerable#find
方法通过评估直到找到与块中的条件匹配的元素为止。第一次将块评估为nil时是否有类似的返回值?想象一个人会有一组哈希:
value = nil
options.each do |o|
break if value = o[:desired]
end
value ||= DEFAULT
有没有一种方法可以实现这个目标?
对集合进行大量转换毫无意义,我希望尽量减少分配数量,因此任何分配新数组的解决方案对我都不利。
答案 0 :(得分:2)
find
方法可用于查找具有最小迭代次数:desired
的第一个元素。
我认为您希望从块中获取desired
键的值而不是元素本身 - Enumerable
中没有任何方法表现得像find
和{{的混合1}} - 你必须使用在块内分配值的外部变量,如下所示。
map
它或多或少看起来像你的代码,它应该也可以正常工作。
如果您想使用options = [{foo: 1}, {desired: 2}, {bar: 3}]
value = nil
options.find do |o|
value = o[:desired]
break if value
end
p value
#=> 2
方法,下面是一种可以使用的方法,但它会迭代所有元素。
Enumerable
答案 1 :(得分:0)
您可以使用reduce:
value = options.reduce(nil){|memo, entry| memo || entry[:desired] } || DEFAULT
答案 2 :(得分:0)
从Ruby 2.0开始,这可以通过将#map
和#find
与lazy enumerables组合在一起来实现:
value = options.lazy.map { |o| o[:desired] }.find { |x| !x.nil? } # or find(&:present?) with ActiveSupport
value ||= DEFAULT
答案 3 :(得分:0)
今天这对我来说很重要:我认为我们可以使用带有reduce值的break
treasure = [1,2,3].reduce(nil) do |memo, value|
break memo if memo
foo(value)
end
答案 4 :(得分:0)
怎么样
options.reduce{ |_,o|
break o if o[:desired]
DEFAULT
}
或
catch do |tag|
options.each{ |_,o| o[:desired] and throw tag, o }
DEFAULT
end
后者允许递归。