Ruby 返回条件值而不是元素值的“find”

Ruby 返回条件值而不是元素值的“find”,ruby,enumerator,Ruby,Enumerator,我正在扫描source中满足条件的元素。该条件通常(但不总是)是regexp匹配。我正在寻找一个版本的find,它返回条件的结果,而不是原始元素。使用find,我必须重新计算成功元素的标准 我计算出的最佳跑步路线如下: source.find {|e| if (m = e.match(/(e.)/)); break m[0]; end} 为了避免分号提示Rubocop抱怨多语句行,我更喜欢这样写: source.find {|e| break m[0] if (m = e.match(/(e.

我正在扫描
source
中满足条件的元素。该条件通常(但不总是)是regexp匹配。我正在寻找一个版本的
find
,它返回条件的结果,而不是原始元素。使用
find
,我必须重新计算成功元素的标准

我计算出的最佳跑步路线如下:

source.find {|e| if (m = e.match(/(e.)/)); break m[0]; end}
为了避免分号提示Rubocop抱怨多语句行,我更喜欢这样写:

source.find {|e| break m[0] if (m = e.match(/(e.)/))}
但是Ruby无法处理前向引用(而且我还没有扭曲到可以将
e
重新用于
m


有没有更优雅的捷径来完成这项工作?

因为你有
中断
,你不需要
查找
来中断。使用
每个

source.each {|e| m = e[/e./] and break m}

虽然我更喜欢@sawa的建议,但您可以使用一个实例变量:

["dog", "cat", "emu", "pig"].find { |e| $da_match = e[/(e.)/] }
  #=> "emu"
$da_match 
  #=> "em"
或者,对于您的正则表达式:

["dog", "cat", "emu", "pig"].find { |e| e =~ /(e.)/ }
  #=> "emu" 
$1
  #=> "em" 
如果正则表达式
r
没有(或可能没有)外部捕获组,则可以添加这样一个组:
/(#{r})/
。比如说,

r0 = /e./
r1 = /(#{r0})/
  #/((?-mix:e.))/

["dog", "cat", "emu", "pig"].find { |e| e =~ r1 }
  #=> "emu" 
$1 
  #=> "em" 
根据正则表达式的使用方式,这可能不起作用。如果(原始)正则表达式包含一个或多个捕获组,则原来的捕获组1将变成捕获组2,依此类推。因此,如果在正则表达式或后续代码中引用了其中一个捕获组的内容,则将获得不正确的值。但是,如果使用命名捕获组并为要添加的外部组保留名称,则这不会是问题:

["dog", "cat", "emu", "pig"].find { |e| e =~ /(?<outer>#{/e./})/ }
  #=> "emu" 
$~[:outer]
  #=> "em"
[“狗”、“猫”、“鸸鹋”、“猪”]。查找{e}e=~/(?{/e./})/}
#=>“emu”
$~[:外部]
#=>“em”

$~
是一个全局变量,包含最新的
匹配数据
对象

过于专注于“发现”和“注入”聪明。谢谢。如果你不知道,你可以对答案进行投票,也可以选择你认为最有帮助的答案。