有没有一种方法可以通过字符串操作创建条件呢?这是我尝试将字符串作为条件传递给include?方法的代码。
"hello eveyone in the house".include?(%w('hello' 'world' 'new\ york' 'place').join(" || ").to_s)
有没有一种方法可以通过字符串操作创建条件呢?这是我尝试将字符串作为条件传递给include?方法的代码。
"hello eveyone in the house".include?(%w('hello' 'world' 'new\ york' 'place').join(" || ").to_s)
include?
函数只接受字符串作为参数,因此无法将条件语句作为参数传递给它。但是你可以编写类似以下的代码:['hello', 'world', 'new york', 'place'].any? { |word|
"hello everyone in the house".include?(word)
}
或者您可以从字符串生成正则表达式:
"hello eveyone in the house".match?(
/#{['hello', 'world', 'new york', 'place'].join('|')}/
)
split 方法可用于字符串分割,set intersection 方法可用于计算集合的交集:
sentence = "hello everyone in the house"
whitelist = %w(hello world new-york place)
found_words = sentence.split & whitelist
p found_words # => ["hello"]
p found_words.empty? # => false
警告:仅当白名单中不包含任何多个单词的字符串时才有效。例如,原问题中的new york
。
如需更健壮的解决方案,请参见@spickermann的答案。
new york
)是无效的。因为在句子new york
中,它将被拆分为['new','york']
,并且与数组[
new york]
不相交。 - spickermann我进行了一些基准测试,以测试速度,令我惊讶的是,在Windows操作系统上,MRI Ruby 2.3.0中Spickerman的第一种解决方案是最快的,其次是交集,而我的解决方案使用Regexp.union却垫底了 :(
require 'benchmark'
s = "hello everyone in the house"
a = ['hello', 'world', 'new york', 'place']
N = 10_000
Benchmark.bmbm do |x|
x.report("Union ") { N.times { s.match(Regexp.union(a)) }}
x.report("Union and scan") { N.times { s.scan(Regexp.union(a)) }}
x.report("Interpollation") { N.times { s.match(/#{a.join('|')}/)}}
x.report("intersect ") { N.times { s.split & a }}
x.report("block ") { N.times { a.any? { |word| s.include?(word)}}}
end
Rehearsal --------------------------------------------------
Union 0.110000 0.000000 0.110000 ( 0.116051)
Union and scan 0.124000 0.000000 0.124000 ( 0.121038)
Interpollation 0.110000 0.000000 0.110000 ( 0.105943)
intersect 0.015000 0.000000 0.015000 ( 0.018456)
block 0.000000 0.000000 0.000000 ( 0.001908)
----------------------------------------- total: 0.359000sec
user system total real
Union 0.109000 0.000000 0.109000 ( 0.111704)
Union and scan 0.125000 0.000000 0.125000 ( 0.119122)
Interpollation 0.109000 0.000000 0.109000 ( 0.105288)
intersect 0.016000 0.000000 0.016000 ( 0.017283)
block 0.000000 0.000000 0.000000 ( 0.001764)
a
的末尾,看看这如何影响结果。目前为止,@spickerman的方法在处理完“hello”后就退出了,而其他方法则继续进行下去。 - Cary SwovelandN
个正则表达式,可以将 Regexp.union
语句移到循环体外部,这样程序可能会更快。 - akuhn
match?
是最近在 Ruby 2.4 中引入的。如果你使用的是旧版本,只需使用match
即可。 - spickermannany?
的优点是它一旦发现字符串就停止执行。 - Eric Duminil