一个“发现” returns 条件值,而不是元素值
A `find` that returns the condition value, not the element value
我正在扫描 source
中满足条件的元素。条件通常(但不总是)是正则表达式匹配。我正在寻找 find
的一个版本,该版本 returns 是条件的结果,而不是原始元素。使用 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
)。
有没有更优雅的东西可以用捷径来完成这项工作?
既然你有break
,你不需要find
来打破。使用 each
.
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"
#=> "em"
如果正则表达式 r
没有(或可能没有)外部捕获组,您可以像这样添加一个:/(#{r})/
。例如,
r0 = /e./
r1 = /(#{r0})/
#/((?-mix:e.))/
["dog", "cat", "emu", "pig"].find { |e| e =~ r1 }
#=> "emu"
#=> "em"
根据正则表达式的使用方式,这可能不起作用。如果(原始)正则表达式包含一个或多个捕获组,则捕获组 1 将变为捕获组 2,依此类推。因此,如果在正则表达式或后续代码中引用其中一个捕获组的内容,将获得不正确的值。但是,如果您使用命名捕获组并为添加的外部捕获组保留名称,这将不是问题:
["dog", "cat", "emu", "pig"].find { |e| e =~ /(?<outer>#{/e./})/ }
#=> "emu"
$~[:outer]
#=> "em"
$~
是包含最近的 MatchData
对象的全局变量。
我正在扫描 source
中满足条件的元素。条件通常(但不总是)是正则表达式匹配。我正在寻找 find
的一个版本,该版本 returns 是条件的结果,而不是原始元素。使用 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
)。
有没有更优雅的东西可以用捷径来完成这项工作?
既然你有break
,你不需要find
来打破。使用 each
.
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"
#=> "em"
如果正则表达式 r
没有(或可能没有)外部捕获组,您可以像这样添加一个:/(#{r})/
。例如,
r0 = /e./
r1 = /(#{r0})/
#/((?-mix:e.))/
["dog", "cat", "emu", "pig"].find { |e| e =~ r1 }
#=> "emu"
#=> "em"
根据正则表达式的使用方式,这可能不起作用。如果(原始)正则表达式包含一个或多个捕获组,则捕获组 1 将变为捕获组 2,依此类推。因此,如果在正则表达式或后续代码中引用其中一个捕获组的内容,将获得不正确的值。但是,如果您使用命名捕获组并为添加的外部捕获组保留名称,这将不是问题:
["dog", "cat", "emu", "pig"].find { |e| e =~ /(?<outer>#{/e./})/ }
#=> "emu"
$~[:outer]
#=> "em"
$~
是包含最近的 MatchData
对象的全局变量。