Ruby Enumerable:获取第一个不是nil的值,但结果必须是what';她在街区里

Ruby Enumerable:获取第一个不是nil的值,但结果必须是what';她在街区里,ruby,enumerable,Ruby,Enumerable,Enumerable#find方法的工作原理是计算,直到找到与块中条件匹配的元素。第一次返回块未计算为零时是否有类似的情况?想象一个人会有一组散列: value = nil options.each do |o| break if value = o[:desired] end value ||= DEFAULT 难道没有一种方法可以做到这一点吗 对集合进行大量转换是没有意义

Enumerable#find
方法的工作原理是计算,直到找到与块中条件匹配的元素。第一次返回块未计算为零时是否有类似的情况?想象一个人会有一组散列:

value = nil
options.each do |o|                     
  break if value = o[:desired]
end                                     
value ||= DEFAULT
难道没有一种方法可以做到这一点吗

对集合进行大量转换是没有意义的,我希望尽量减少分配的数量,因此任何分配新数组的解决方案都不会对我有好处

您可以使用:


find
方法将用于查找具有
:所需
键且迭代次数最少的第一个元素

我认为您希望从块而不是元素本身获取
所需的
键的值-在
可枚举的
中没有一种方法的行为类似于
查找
映射
的混合-您必须使用块内赋值的外部变量,如下所示

options = [{foo: 1}, {desired: 2}, {bar: 3}]

value = nil
options.find do |o|
  value = o[:desired]
  break if value
end

p value
#=> 2
它或多或少看起来像您的代码,也应该可以正常工作

如果您想使用
Enumerable
方法,下面是一种可以使用的方法,但它将迭代所有元素

p value = options.map { |o| value = o[:desired] }.compact.first

从Ruby 2.0开始,这可以通过将
#map
#find
与以下内容相结合来实现:


今天我想到了这个:我想我们可以使用break和reduce的值

treasure = [1,2,3].reduce(nil) do |memo, value|
  break memo if memo
  foo(value)
end
怎么样

options.reduce{ |_,o|
   break o if o[:desired]
   DEFAULT
}


后者允许递归。

不确定这是否是您所要求的,但不只是否定
nil?
检查您的出价吗?我认为他希望首先找到具有
:所需
key@SteveTurczyn我理解了他现在所问的问题——谢谢你用我先前的回答指出了这个缺陷。它不会解析这个问题吗选项集合直到结束?这就是我想要避免的
#find
将在匹配后立即停止求值。正确,但也可以使用一个值中断求值-请参见我的答案您是否介意编辑您的答案,以简要说明这与以前的现有答案有何不同?
treasure = [1,2,3].reduce(nil) do |memo, value|
  break memo if memo
  foo(value)
end
options.reduce{ |_,o|
   break o if o[:desired]
   DEFAULT
}
catch do |tag|
   options.each{ |_,o| o[:desired] and throw tag, o }
   DEFAULT
end