检查字符串变量是否在一组字符串中

时间:2022-09-14 23:49:06

Which one is better:

哪一个更好:

x == 'abc' || x == 'def' || x == 'ghi'
%w(abc def ghi).include? x
x =~ /abc|def|ghi/

?

3 个解决方案

#1


7  

Which one is better? The question can't be easily answered, because they don't all do the same things.

哪一个更好?这个问题不容易回答,因为他们并非都做同样的事情。

x == 'abc' || x == 'def' || x == 'ghi'
%w(abc def ghi).include? x

compare x against fixed strings for equality. x has to be one of those values. Between those two I tend to go with the second because it's easier to maintain. Imagine what it would look like if you had to compare against twenty, fifty or one hundred strings.

比较x与固定字符串的相等性。 x必须是其中一个值。在这两者之间,我倾向于选择第二种,因为它更容易维护。想象一下,如果必须与二十,五十或一百个字符串进行比较,它会是什么样子。

The third test:

第三个测试:

x ~= /abc|def|ghi/

matches substrings:

x = 'xyzghi'
(x =~ /abc|def|ghi/) # => 3

so it isn't the same as the first two.

所以它与前两个不一样。

EDIT: There are some things in the benchmarks done by nash that I'd do differently. Using Ruby 1.9.2-p180 on a MacBook Pro, this tests 1,000,000 loops and compares the results of anchoring the regex, using grouping, along with not splitting the %w() array each time through the loop:

编辑:纳什完成的基准测试中有一些事情我会采用不同的方式。在MacBook Pro上使用Ruby 1.9.2-p180,测试1,000,000个循环,并使用分组比较锚定正则表达式的结果,以及每次循环时不拆分%w()数组:

require 'benchmark'
str = "test"

n = 1_000_000
Benchmark.bm do |x|
  x.report { n.times { str == 'abc' || str == 'def' || str == 'ghi' } }
  x.report { n.times { %w(abc def ghi).include? str } }
  x.report { ary = %w(abc def ghi); n.times { ary.include? str } }
  x.report { n.times { str =~ /abc|def|ghi/ } }
  x.report { n.times { str =~ /^abc|def|ghi$/ } }
  x.report { n.times { str =~ /^(abc|def|ghi)$/ } }
  x.report { n.times { str =~ /^(?:abc|def|ghi)$/ } }
  x.report { n.times { str =~ /\b(?:abc|def|ghi)\b/ } }
end
# >>       user     system      total        real
# >>   1.160000   0.000000   1.160000 (  1.165331)
# >>   1.920000   0.000000   1.920000 (  1.920120)
# >>   0.990000   0.000000   0.990000 (  0.983921)
# >>   1.070000   0.000000   1.070000 (  1.068140)
# >>   1.050000   0.010000   1.060000 (  1.054852)
# >>   1.060000   0.000000   1.060000 (  1.063909)
# >>   1.060000   0.000000   1.060000 (  1.050813)
# >>   1.050000   0.000000   1.050000 (  1.056147)

#2


2  

The first might be a tad quicker, since there are no method calls and your doing straight string comparisons, but its also probably the least readable and least maintainable.

第一个可能会更快,因为没有方法调用和你进行直接字符串比较,但它也可能是最不可读和最不可维护的。

The second is definitely the grooviest, and the ruby way of going about it. It's the most maintainable, and probably the best to read.

第二个绝对是最时髦的,也是最常见的红宝石方式。它是最易于维护的,也许是最好阅读的。

The last way uses old school perl regex syntax. Fairly fast, not as annoying as the first to maintain, fairly readable.

最后一种方法使用旧式perl正则表达式语法。相当快,不像第一个维护,相当可读。

I guess it depends what you mean by "better".

我想这取决于你的意思是“更好”。

#3


2  

some benchmarks:

require 'benchmark'
str = "test"
Benchmark.bm do |x|
  x.report {100000.times {if str == 'abc' || str == 'def' || str == 'ghi'; end}}
  x.report {100000.times {if %w(abc def ghi).include? str; end}}
  x.report {100000.times {if str =~ /abc|def|ghi/; end}}
end

    user     system      total        real
0.250000   0.000000   0.250000 (  0.251014)
0.374000   0.000000   0.374000 (  0.402023)
0.265000   0.000000   0.265000 (  0.259014)

So as you can see the first way works faster then other. And the longer str, the slower the last way works:

所以你可以看到第一种方式比其他方式更快。而str越长,最后一种方式越慢:

str = "testasdasdasdasdasddkmfskjndfbdkjngdjgndksnfg"
    user     system      total        real
0.234000   0.000000   0.234000 (  0.248014)
0.405000   0.000000   0.405000 (  0.403023)
1.046000   0.000000   1.046000 (  1.038059)

#1


7  

Which one is better? The question can't be easily answered, because they don't all do the same things.

哪一个更好?这个问题不容易回答,因为他们并非都做同样的事情。

x == 'abc' || x == 'def' || x == 'ghi'
%w(abc def ghi).include? x

compare x against fixed strings for equality. x has to be one of those values. Between those two I tend to go with the second because it's easier to maintain. Imagine what it would look like if you had to compare against twenty, fifty or one hundred strings.

比较x与固定字符串的相等性。 x必须是其中一个值。在这两者之间,我倾向于选择第二种,因为它更容易维护。想象一下,如果必须与二十,五十或一百个字符串进行比较,它会是什么样子。

The third test:

第三个测试:

x ~= /abc|def|ghi/

matches substrings:

x = 'xyzghi'
(x =~ /abc|def|ghi/) # => 3

so it isn't the same as the first two.

所以它与前两个不一样。

EDIT: There are some things in the benchmarks done by nash that I'd do differently. Using Ruby 1.9.2-p180 on a MacBook Pro, this tests 1,000,000 loops and compares the results of anchoring the regex, using grouping, along with not splitting the %w() array each time through the loop:

编辑:纳什完成的基准测试中有一些事情我会采用不同的方式。在MacBook Pro上使用Ruby 1.9.2-p180,测试1,000,000个循环,并使用分组比较锚定正则表达式的结果,以及每次循环时不拆分%w()数组:

require 'benchmark'
str = "test"

n = 1_000_000
Benchmark.bm do |x|
  x.report { n.times { str == 'abc' || str == 'def' || str == 'ghi' } }
  x.report { n.times { %w(abc def ghi).include? str } }
  x.report { ary = %w(abc def ghi); n.times { ary.include? str } }
  x.report { n.times { str =~ /abc|def|ghi/ } }
  x.report { n.times { str =~ /^abc|def|ghi$/ } }
  x.report { n.times { str =~ /^(abc|def|ghi)$/ } }
  x.report { n.times { str =~ /^(?:abc|def|ghi)$/ } }
  x.report { n.times { str =~ /\b(?:abc|def|ghi)\b/ } }
end
# >>       user     system      total        real
# >>   1.160000   0.000000   1.160000 (  1.165331)
# >>   1.920000   0.000000   1.920000 (  1.920120)
# >>   0.990000   0.000000   0.990000 (  0.983921)
# >>   1.070000   0.000000   1.070000 (  1.068140)
# >>   1.050000   0.010000   1.060000 (  1.054852)
# >>   1.060000   0.000000   1.060000 (  1.063909)
# >>   1.060000   0.000000   1.060000 (  1.050813)
# >>   1.050000   0.000000   1.050000 (  1.056147)

#2


2  

The first might be a tad quicker, since there are no method calls and your doing straight string comparisons, but its also probably the least readable and least maintainable.

第一个可能会更快,因为没有方法调用和你进行直接字符串比较,但它也可能是最不可读和最不可维护的。

The second is definitely the grooviest, and the ruby way of going about it. It's the most maintainable, and probably the best to read.

第二个绝对是最时髦的,也是最常见的红宝石方式。它是最易于维护的,也许是最好阅读的。

The last way uses old school perl regex syntax. Fairly fast, not as annoying as the first to maintain, fairly readable.

最后一种方法使用旧式perl正则表达式语法。相当快,不像第一个维护,相当可读。

I guess it depends what you mean by "better".

我想这取决于你的意思是“更好”。

#3


2  

some benchmarks:

require 'benchmark'
str = "test"
Benchmark.bm do |x|
  x.report {100000.times {if str == 'abc' || str == 'def' || str == 'ghi'; end}}
  x.report {100000.times {if %w(abc def ghi).include? str; end}}
  x.report {100000.times {if str =~ /abc|def|ghi/; end}}
end

    user     system      total        real
0.250000   0.000000   0.250000 (  0.251014)
0.374000   0.000000   0.374000 (  0.402023)
0.265000   0.000000   0.265000 (  0.259014)

So as you can see the first way works faster then other. And the longer str, the slower the last way works:

所以你可以看到第一种方式比其他方式更快。而str越长,最后一种方式越慢:

str = "testasdasdasdasdasddkmfskjndfbdkjngdjgndksnfg"
    user     system      total        real
0.234000   0.000000   0.234000 (  0.248014)
0.405000   0.000000   0.405000 (  0.403023)
1.046000   0.000000   1.046000 (  1.038059)