如何"or"数组范围内的所有元素



我试图在一行上一直说if x == consonants[0] or [1] or [2][21]。出于某种原因,我认为consonants[0..21]会工作,但它没有:

consonants = ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t",
"v", "w", "x", "y", "z"]
new_first = ["m", "a", "t", "t", "h", "e", "w", "s"]

new_first.each do |x|
if x == consonants[0]
    puts x.next!
elsif x == consonants[1]
    puts x.next!
elsif x == consonants[2]
    puts x.next!
elsif x == consonants[3]
    puts x.next!    
else
    puts "test failed"
end
end

有几种方法可以解决这个问题,但这取决于您对性能的关注,以及需要多大的可扩展性。通常,x == yx == z形式的if语句链可以折叠成:

 case (x)
 when y, z
   # ... Executed on a match
 end

在你的情况下,你甚至可以使用你的数组作为一个有效值的列表来做到这一点:

 case (x)
 when *constants
   puts x.next!
 end

对于较大的列表,您可能希望将其折叠成一个Set,因为它们针对include?测试进行了优化:

consonants_set = Set.new(consonants)
if (consonants_set.include?(x))
  puts x.next!
end

因为你在做单个字母匹配,你有更多的选择。例如,正则表达式

consonants_regexp = Regexp.new('[%s]' % consonants.join)
if (consonants_regexp.match(x))
  puts x.next!
end

或者你甚至可以做一个简单的子字符串匹配:

consonants_string = consonants.join
if (consonants_string[x])
  puts x.next!
end

值得注意,但是您可以遍历字符串中的字符:

'cwzbrly'.each_char do |c|
  puts c
end

这避免了创建和/或输入[ 'a', 'b', ... ]形式的长数组的需要。

你可以这样做:

if consonants.include? (x)
     your-code-here
end

检查数组中是否有等于x的元素

可以使用正则表达式

if x =~ /[aeiou]/
  puts 'test failed'
else
  puts x.next!    
end

/[aeiou]/表示匹配a, e, i, o或u。

这将消除创建辅音数组的需要。

如果我正确理解并且您期望nuuixt结果,您可以这样做:

new_first.select { |letter| consonants.include?(letter) && letter.next! }

&&在这里是这样工作的:如果consonants.include?(letter)求值为true,则block返回letter.next!

考虑一下:

consonants = ('a' .. 'z').to_a - %w[a e i o u] # => ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z"]
shifted_consonants = consonants.zip(consonants.rotate).to_h # => {"b"=>"c", "c"=>"d", "d"=>"f", "f"=>"g", "g"=>"h", "h"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"v", "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"b"}
'matthews'.chars.map{ |c| shifted_consonants[c] || c } # => ["n", "a", "v", "v", "j", "e", "x", "t"]

'a''z'的范围并将其转换为数组,然后减去元音数组,只得到辅音。

接下来,它将辅音数组转换为哈希/查找表shifted_consonants,其中每个键是当前辅音,值是下一个辅音。

最后,它获取'matthews'中的每个字符,并查看shifted_consonants中是否有对应该字符的值。如果不是,则返回nil,它触发||并返回当前字符。如果在散列中有命中,则返回该辅音字母的下一个值,该值将短路||"或"。

另一种方法是利用tr:

consonants = (('a' .. 'z').to_a - %w[a e i o u]).join # => "bcdfghjklmnpqrstvwxyz"
shifted_consonants = consonants.chars.rotate.join # => "cdfghjklmnpqrstvwxyzb"
'matthews'.tr(consonants, shifted_consonants).chars # => ["n", "a", "v", "v", "j", "e", "x", "t"]

检查速度:

CONSONANTS = ('a' .. 'z').to_a - %w[a e i o u] # => ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z"]
SHIFTED_CONSONANTS_HASH = CONSONANTS.zip(CONSONANTS.rotate).to_h # => {"b"=>"c", "c"=>"d", "d"=>"f", "f"=>"g", "g"=>"h", "h"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"v", "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"b"}
CONSONANTS_STR = (('a' .. 'z').to_a - %w[a e i o u]).join # => "bcdfghjklmnpqrstvwxyz"
SHIFTED_CONSONANTS_STR = CONSONANTS_STR.chars.rotate.join # => "cdfghjklmnpqrstvwxyzb"
require 'fruity'
sample_string = 'matthews'
compare  do
  use_hash { sample_string.chars.map{ |c| SHIFTED_CONSONANTS_HASH[c] || c } }
  use_tr { sample_string.tr(CONSONANTS_STR, SHIFTED_CONSONANTS_STR).chars }
end
# >> Running each test 2048 times. Test will take about 1 second.
# >> use_tr is faster than use_hash by 10.000000000000009% ± 10.0%

样本字符串越长,差异越大。改变:

sample_string = 'matthews' * 1000

我看到的结果是:

# >> Running each test 4 times. Test will take about 1 second.
# >> use_tr is faster than use_hash by 4x ± 0.1

在评论中发现,不是在它所属的问题中…

我的目标是将arraynew_first = ["m", "a",

的常量改为下一个辅音,元音改为下一个元音。

调整这里有一些变化。您可以解开delta:

ALPHABET = ('a' .. 'z').to_a
VOWELS = %w[a e i o u]
CONSONANTS = ALPHABET - VOWELS # => ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z"]
SHIFTED_CONSONANTS = CONSONANTS.rotate # => ["c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z", "b"]
SHIFTED_VOWELS = VOWELS.rotate # => ["e", "i", "o", "u", "a"]
SHIFTED_CONSONANTS_HASH = CONSONANTS.zip(SHIFTED_CONSONANTS).to_h # => {"b"=>"c", "c"=>"d", "d"=>"f", "f"=>"g", "g"=>"h", "h"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"v", "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"b"}
SHIFTED_VOWELS_HASH = VOWELS.zip(SHIFTED_VOWELS).to_h # => {"a"=>"e", "e"=>"i", "i"=>"o", "o"=>"u", "u"=>"a"}
sample_string = 'matthews'
sample_string.chars.map{ |c| SHIFTED_CONSONANTS_HASH[c] || SHIFTED_VOWELS_HASH[c] } # => ["n", "e", "v", "v", "j", "i", "x", "t"]

CONSONANTS_STR = CONSONANTS.join # => "bcdfghjklmnpqrstvwxyz"
SHIFTED_CONSONANTS_STR = SHIFTED_CONSONANTS.join # => "cdfghjklmnpqrstvwxyzb"
SHIFTED_VOWELS_STR = SHIFTED_VOWELS.join # => "eioua"
CHARACTERS_STR = (CONSONANTS + VOWELS).join # => "bcdfghjklmnpqrstvwxyzaeiou"
SHIFTED_CHARACTERS_STR = SHIFTED_CONSONANTS_STR + SHIFTED_VOWELS_STR # => "cdfghjklmnpqrstvwxyzbeioua"
sample_string.tr(CHARACTERS_STR, SHIFTED_CHARACTERS_STR).chars # => ["n", "e", "v", "v", "j", "i", "x", "t"]

这些变化不会影响实际代码的速度:tr仍然会超过使用哈希查找。

最新更新