我试图在一行上一直说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 == y
和x == 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
仍然会超过使用哈希查找。