[英]Ruby Iterating over an array and find match in an hash and replace the element in array
我希望有人澄清我如何可能遍历数组,在 hash[value] 中找到完全匹配,并用 hash[key] 替换数组中的元素。
例如,如果我有一个莫尔斯目录morse_dict = { "a" => ".-","b" => "-...","c" => "-.-.","d" => "-..","e" => ".","f" => "..-.","g" => "--.","h" => "....","i" => "..","j" => ".---","k" => "-.-","l" => ".-..","m" => "--","n" => "-.","o" => "---","p" => ".--.","q" => "--.-","r" => ".-.","s" => "...","t" => "-","u" => "..-","v" => "...-","w" => ".--","x" => "-..-","y" => "-.--","z" => "--.."," " => " ","1" => ".----","2" => "..---","3" => "...--","4" => "....-","5" => ".....","6" => "-....","7" => "--...","8" => "---..","9" => "----.","0" => "-----" }
并且我想要一种方法,该方法对于莫尔斯电码中的给定字符串返回常规字母表中的字符串。 这是 codewars kata 。
我对挑战本身的解决方案不感兴趣,我想了解它的原理。
到目前为止,我想过这样做:
def morse_code(arr)
arr.split(" ").each {|element|
element.each_char {|char|
(morse_dict.include?(char)) ? (print "true") : (print "false")}
}
end
我只打印 false,这意味着我实际上并没有在哈希中寻找匹配项。
使用Hash#key而不替换数组,而是创建一个新数组(使用map!
进行替换):
array = [1,2,3,4,5]
hash = {a: 4, b: 7, c: 3}
array.map { |el| hash.key(el) }
# => [nil, nil, :c, :a, nil]
您可能想考虑使用Hash#invert并出于性能原因简单地通过键引用元素,因为Hash#key
是O(n)
而Hash#[]
是O(1)
。
array = [1,2,3,4,5]
hash = {a: 4, b: 7, c: 3}
inverted_hash = hash.invert
array.map { |el| inverted_hash[el] }
# => [nil, nil, :c, :a, nil]
假设: arr = 'abc d'
,这不是 arr,所以请制作 morse_string
def morse_code(morse_string)
new_elements = []
# iterate over each character in the string,
morse_string.split(" ").each do |element|
if morse_dict[element]
# https://apidock.com/ruby/Array/push
new_elements.push( morse_dict[element] )
else
# whatever you want to do when there is no match
end
end
# re-create the string again, but with braille
# https://apidock.com/ruby/Array/join
new_elements.join(' ')
end
morse_string = 'a b c d'
morse_code(morse_string)
我从 kata 中了解到,字母应由一个空格分隔,单词应由三个空格分隔。
作为第一步,我将对哈希morse_dict
两项更改:删除密钥' '
; 并为一些标点字符添加键值对。 不需要空格键; kata 中讨论了对标点符号的需求。
PUNCTUATION = { "."=>".-.-.-", ","=>"--..--", "?"=>"..--..", "!"=>"-.-.--" }
ALPHA_TO_MORSE = dict.reject { |k,_| k == " " }.merge(PUNCTUATION)
#=> {"a"=>".-", "b"=>"-...", "c"=>"-.-.", "d"=>"-..", "e"=>".", "f"=>"..-.",
# "g"=>"--.", "h"=>"....", "i"=>"..", "j"=>".---", "k"=>"-.-", "l"=>".-..",
# "m"=>"--", "n"=>"-.", "o"=>"---", "p"=>".--.", "q"=>"--.-", "r"=>".-.",
# "s"=>"...", "t"=>"-", "u"=>"..-", "v"=>"...-", "w"=>".--", "x"=>"-..-",
# "y"=>"-.--", "z"=>"--..", "1"=>".----", "2"=>"..---", "3"=>"...--",
# "4"=>"....-", "5"=>".....", "6"=>"-....", "7"=>"--...", "8"=>"---..",
# "9"=>"----.", "0"=>"-----", "."=>".-.-.-", ","=>"--..--", "?"=>"..--..",
# "!"=>"-.-.--"}
我从Morse Code Wiki获得了标点符号的摩尔斯电码。 如果需要,可以添加额外的标点符号。
散列ALPHA_TO_MORSE
用于编码文本。 解码莫尔斯电码中的消息需要此散列的倒数。 解码还需要键值对"...---..."=>"sos"
。
MORSE_TO_ALPHA = ALPHA_TO_MORSE.invert.merge("...---..."=>"sos")
#=> {".-"=>"a", "-..."=>"b", "-.-."=>"c", "-.."=>"d", "."=>"e", "..-."=>"f",
# "--."=>"g", "...."=>"h", ".."=>"i", ".---"=>"j", "-.-"=>"k", ".-.."=>"l",
# "--"=>"m", "-."=>"n", "---"=>"o", ".--."=>"p", "--.-"=>"q", ".-."=>"r",
# "..."=>"s", "-"=>"t", "..-"=>"u", "...-"=>"v", ".--"=>"w", "-..-"=>"x",
# "-.--"=>"y", "--.."=>"z", ".----"=>"1", "..---"=>"2", "...--"=>"3",
# "....-"=>"4", "....."=>"5", "-...."=>"6", "--..."=>"7", "---.."=>"8",
# "----."=>"9", "-----"=>"0", ".-.-.-"=>".", "--..--"=>",",
# "..--.."=>"?", "-.-.--"=>"!""...---..."=>"sos"}
还需要一个散列来处理消息"sos"
(或"SOS"
莫尔斯电码不区分大小写)或"sos"
后跟标点字符(例如, "sos!"
)要被编码的情况. 1见维基。
SOS_WITH_PUNCTUATION = PUNCTUATION.each_with_object({}) { |(k,v),h|
h["sos#{k}"] = "...---... #{v}" }.merge('sos'=>"...---...")
#=> {"sos."=>"...---... .-.-.-", "sos,"=>"...---... --..--",
# "sos?"=>"...---... ..--..", "sos!"=>"...---... -.-.--", "sos"=>"...---..."}
编码和解码方法如下。 encode
检查字符串中的每个单词是否是散列SOS_WITH_PUNCTUATION
中的一个键。 如果是,key 的值就是单词的摩尔斯电码; 否则,单词被分成字母,每个字母被翻译成摩尔斯电码。
def encode(str)
str.strip.downcase.split.map do |word|
if SOS_WITH_PUNCTUATION.key?(word)
SOS_WITH_PUNCTUATION[word]
else
word.each_char.map { |c| ALPHA_TO_MORSE[c] }.join(' ')
end
end.join (' ')
end
def decode(morse)
morse.strip.split(/ {3}/).map do |word|
word.split.map { |c| MORSE_TO_ALPHA[c] }.join
end.join(' ')
end
我们现在可以试试这两种方法。
str = " Is now the time for you, and 007, to send an SOS?"
morse = encode str
#=> ".. ... -. --- .-- - .... . - .. -- . ..-. --- .-. -.-- --- ..- --..-- .- -. -.. ----- ----- --... --..-- - --- ... . -. -.. .- -. ...---... ..--.."
decode morse
#=> "is now the time for you, and 007, to send an sos?"
1 如果有一个预处理步骤来转换,比如"sos."
,会更简单"sos."
到"sos ."
,但是当生成的摩尔斯电码被解码时, "sos"
和"."
之间会有一个空格"."
. 我想密码学家可以解决这个问题,但我选择避免插入空格。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.