Ruby Iterating over an array and find match in an hash and replace the element in array











up vote
1
down vote

favorite












I would like someone to clarify how can I possibly iterating over an array, find an exact match in an hash[value], and replace the element in the array with the hash[key].



As example, if I have a morse directory 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" => "-----"
}



and I want a method that for a given string in morse code returns a string in regular alphabet.
This is the codewars kata.



I am not interested in the solution to the challenge itself, I would like to understand the principle of this.



So far I have thought of proceeding this way:



def morse_code(arr)
arr.split(" ").each {|element|
element.each_char {|char|
(morse_dict.include?(char)) ? (print "true") : (print "false")}
}
end


I only print false, which means that I am not actually looking for match into the hash.










share|improve this question




























    up vote
    1
    down vote

    favorite












    I would like someone to clarify how can I possibly iterating over an array, find an exact match in an hash[value], and replace the element in the array with the hash[key].



    As example, if I have a morse directory 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" => "-----"
    }



    and I want a method that for a given string in morse code returns a string in regular alphabet.
    This is the codewars kata.



    I am not interested in the solution to the challenge itself, I would like to understand the principle of this.



    So far I have thought of proceeding this way:



    def morse_code(arr)
    arr.split(" ").each {|element|
    element.each_char {|char|
    (morse_dict.include?(char)) ? (print "true") : (print "false")}
    }
    end


    I only print false, which means that I am not actually looking for match into the hash.










    share|improve this question


























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I would like someone to clarify how can I possibly iterating over an array, find an exact match in an hash[value], and replace the element in the array with the hash[key].



      As example, if I have a morse directory 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" => "-----"
      }



      and I want a method that for a given string in morse code returns a string in regular alphabet.
      This is the codewars kata.



      I am not interested in the solution to the challenge itself, I would like to understand the principle of this.



      So far I have thought of proceeding this way:



      def morse_code(arr)
      arr.split(" ").each {|element|
      element.each_char {|char|
      (morse_dict.include?(char)) ? (print "true") : (print "false")}
      }
      end


      I only print false, which means that I am not actually looking for match into the hash.










      share|improve this question















      I would like someone to clarify how can I possibly iterating over an array, find an exact match in an hash[value], and replace the element in the array with the hash[key].



      As example, if I have a morse directory 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" => "-----"
      }



      and I want a method that for a given string in morse code returns a string in regular alphabet.
      This is the codewars kata.



      I am not interested in the solution to the challenge itself, I would like to understand the principle of this.



      So far I have thought of proceeding this way:



      def morse_code(arr)
      arr.split(" ").each {|element|
      element.each_char {|char|
      (morse_dict.include?(char)) ? (print "true") : (print "false")}
      }
      end


      I only print false, which means that I am not actually looking for match into the hash.







      arrays ruby hash iteration






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 at 23:10









      Cary Swoveland

      66.8k53865




      66.8k53865










      asked Nov 11 at 19:12









      Floroz

      85




      85
























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          I understand from the kata that letters are to be separated by one space and words by three spaces.



          As a first step I will two changes to the hash morse_dict: remove the key ' '; and add key-value pairs for some punctuation characters. The space character key is not needed; the need for punctuation codes is discussed in the 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"=>"-----", "."=>".-.-.-", ","=>"--..--", "?"=>"..--..",
          # "!"=>"-.-.--"}


          I obtained the Morse codes for the punctuation characters from the Morse Code Wiki. Additional punctuation characters could be added if desired.



          The hash ALPHA_TO_MORSE is used in encoding text. The inverse of this hash is needed for decoding messages in Morse code. Also needed for decoding is the key value pair "...---..."=>"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"}


          One more hash is needed to deal with cases where the message "sos" (or "SOS"--Morse code is case insensitive), or "sos" followed by a punctuation character (e.g., "sos!") is to be encoded.1 See the Wiki.



          SOS_WITH_PUNCTUATION = PUNCTUATION.each_with_object({}) { |(k,v),h|
          h["sos#{k}"] = "...---... #{v}" }.merge('sos'=>"...---...")
          #=> {"sos."=>"...---... .-.-.-", "sos,"=>"...---... --..--",
          # "sos?"=>"...---... ..--..", "sos!"=>"...---... -.-.--", "sos"=>"...---..."}


          The encoding and decoding methods follow. encode checks to see if each word in the string is a key in the hash SOS_WITH_PUNCTUATION. If it is, the value of key is the Morse code for the word; else, the word is divided into letters and each letter is translated into Morse code.



          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


          We can now try out these two methods.



          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 It would be simpler to have a pre-processing step that would convert, say, "sos." to "sos .", but when the resulting Morse code were decoded there would be a space between "sos" and ".". I suppose that cryptographers could deal with that, but I've chosen to avoid the insertion of the space.






          share|improve this answer























          • Manipulate the string directly works, however I receive this error rb:60:in block in describe: Expected: "SOS", instead got: nil (Test::Error) I have added SOS to the dictionary and paired with '...---..." but it still returns nil
            – Floroz
            Nov 12 at 11:36












          • What is not clear in "dividing into an array" is: you .split your string morse into an array of single morse word, then iterate over the single word, then I don't understand exactly the next iteration when you .join the value of MORSE_TO_ALPHA.
            – Floroz
            Nov 12 at 11:43












          • Floors, I apologize for not replying to your comments earlier. I somehow missed them. It’s late now so I’ll look into the problems you mention tomorrow.
            – Cary Swoveland
            Nov 13 at 9:19










          • Thank you Cary, I have actually managed to get past the issue by inserting the "SOS" in the dictionary manually and added an if statement just to ensure I could pass the test, and incurred in another error using the different versions of your code as it does not encode back the punctuation (".,!?").
            – Floroz
            Nov 13 at 14:12












          • Floroz, I've edited my answer.
            – Cary Swoveland
            Nov 15 at 4:34


















          up vote
          1
          down vote













          Using Hash#key without replacing the array, rather creating a new one (use map! for replacement):



          array = [1,2,3,4,5]    
          hash = {a: 4, b: 7, c: 3}

          array.map { |el| hash.key(el) }
          # => [nil, nil, :c, :a, nil]


          You may want to think about using Hash#invert and simply referencing the elements by keys for performance reasons as Hash#key is O(n) while Hash# is 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]





          share|improve this answer






























            up vote
            0
            down vote













            assuming: arr = 'a b c d', which is not an arr, so please make that 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)





            share|improve this answer





















              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252238%2fruby-iterating-over-an-array-and-find-match-in-an-hash-and-replace-the-element-i%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              0
              down vote



              accepted










              I understand from the kata that letters are to be separated by one space and words by three spaces.



              As a first step I will two changes to the hash morse_dict: remove the key ' '; and add key-value pairs for some punctuation characters. The space character key is not needed; the need for punctuation codes is discussed in the 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"=>"-----", "."=>".-.-.-", ","=>"--..--", "?"=>"..--..",
              # "!"=>"-.-.--"}


              I obtained the Morse codes for the punctuation characters from the Morse Code Wiki. Additional punctuation characters could be added if desired.



              The hash ALPHA_TO_MORSE is used in encoding text. The inverse of this hash is needed for decoding messages in Morse code. Also needed for decoding is the key value pair "...---..."=>"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"}


              One more hash is needed to deal with cases where the message "sos" (or "SOS"--Morse code is case insensitive), or "sos" followed by a punctuation character (e.g., "sos!") is to be encoded.1 See the Wiki.



              SOS_WITH_PUNCTUATION = PUNCTUATION.each_with_object({}) { |(k,v),h|
              h["sos#{k}"] = "...---... #{v}" }.merge('sos'=>"...---...")
              #=> {"sos."=>"...---... .-.-.-", "sos,"=>"...---... --..--",
              # "sos?"=>"...---... ..--..", "sos!"=>"...---... -.-.--", "sos"=>"...---..."}


              The encoding and decoding methods follow. encode checks to see if each word in the string is a key in the hash SOS_WITH_PUNCTUATION. If it is, the value of key is the Morse code for the word; else, the word is divided into letters and each letter is translated into Morse code.



              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


              We can now try out these two methods.



              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 It would be simpler to have a pre-processing step that would convert, say, "sos." to "sos .", but when the resulting Morse code were decoded there would be a space between "sos" and ".". I suppose that cryptographers could deal with that, but I've chosen to avoid the insertion of the space.






              share|improve this answer























              • Manipulate the string directly works, however I receive this error rb:60:in block in describe: Expected: "SOS", instead got: nil (Test::Error) I have added SOS to the dictionary and paired with '...---..." but it still returns nil
                – Floroz
                Nov 12 at 11:36












              • What is not clear in "dividing into an array" is: you .split your string morse into an array of single morse word, then iterate over the single word, then I don't understand exactly the next iteration when you .join the value of MORSE_TO_ALPHA.
                – Floroz
                Nov 12 at 11:43












              • Floors, I apologize for not replying to your comments earlier. I somehow missed them. It’s late now so I’ll look into the problems you mention tomorrow.
                – Cary Swoveland
                Nov 13 at 9:19










              • Thank you Cary, I have actually managed to get past the issue by inserting the "SOS" in the dictionary manually and added an if statement just to ensure I could pass the test, and incurred in another error using the different versions of your code as it does not encode back the punctuation (".,!?").
                – Floroz
                Nov 13 at 14:12












              • Floroz, I've edited my answer.
                – Cary Swoveland
                Nov 15 at 4:34















              up vote
              0
              down vote



              accepted










              I understand from the kata that letters are to be separated by one space and words by three spaces.



              As a first step I will two changes to the hash morse_dict: remove the key ' '; and add key-value pairs for some punctuation characters. The space character key is not needed; the need for punctuation codes is discussed in the 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"=>"-----", "."=>".-.-.-", ","=>"--..--", "?"=>"..--..",
              # "!"=>"-.-.--"}


              I obtained the Morse codes for the punctuation characters from the Morse Code Wiki. Additional punctuation characters could be added if desired.



              The hash ALPHA_TO_MORSE is used in encoding text. The inverse of this hash is needed for decoding messages in Morse code. Also needed for decoding is the key value pair "...---..."=>"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"}


              One more hash is needed to deal with cases where the message "sos" (or "SOS"--Morse code is case insensitive), or "sos" followed by a punctuation character (e.g., "sos!") is to be encoded.1 See the Wiki.



              SOS_WITH_PUNCTUATION = PUNCTUATION.each_with_object({}) { |(k,v),h|
              h["sos#{k}"] = "...---... #{v}" }.merge('sos'=>"...---...")
              #=> {"sos."=>"...---... .-.-.-", "sos,"=>"...---... --..--",
              # "sos?"=>"...---... ..--..", "sos!"=>"...---... -.-.--", "sos"=>"...---..."}


              The encoding and decoding methods follow. encode checks to see if each word in the string is a key in the hash SOS_WITH_PUNCTUATION. If it is, the value of key is the Morse code for the word; else, the word is divided into letters and each letter is translated into Morse code.



              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


              We can now try out these two methods.



              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 It would be simpler to have a pre-processing step that would convert, say, "sos." to "sos .", but when the resulting Morse code were decoded there would be a space between "sos" and ".". I suppose that cryptographers could deal with that, but I've chosen to avoid the insertion of the space.






              share|improve this answer























              • Manipulate the string directly works, however I receive this error rb:60:in block in describe: Expected: "SOS", instead got: nil (Test::Error) I have added SOS to the dictionary and paired with '...---..." but it still returns nil
                – Floroz
                Nov 12 at 11:36












              • What is not clear in "dividing into an array" is: you .split your string morse into an array of single morse word, then iterate over the single word, then I don't understand exactly the next iteration when you .join the value of MORSE_TO_ALPHA.
                – Floroz
                Nov 12 at 11:43












              • Floors, I apologize for not replying to your comments earlier. I somehow missed them. It’s late now so I’ll look into the problems you mention tomorrow.
                – Cary Swoveland
                Nov 13 at 9:19










              • Thank you Cary, I have actually managed to get past the issue by inserting the "SOS" in the dictionary manually and added an if statement just to ensure I could pass the test, and incurred in another error using the different versions of your code as it does not encode back the punctuation (".,!?").
                – Floroz
                Nov 13 at 14:12












              • Floroz, I've edited my answer.
                – Cary Swoveland
                Nov 15 at 4:34













              up vote
              0
              down vote



              accepted







              up vote
              0
              down vote



              accepted






              I understand from the kata that letters are to be separated by one space and words by three spaces.



              As a first step I will two changes to the hash morse_dict: remove the key ' '; and add key-value pairs for some punctuation characters. The space character key is not needed; the need for punctuation codes is discussed in the 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"=>"-----", "."=>".-.-.-", ","=>"--..--", "?"=>"..--..",
              # "!"=>"-.-.--"}


              I obtained the Morse codes for the punctuation characters from the Morse Code Wiki. Additional punctuation characters could be added if desired.



              The hash ALPHA_TO_MORSE is used in encoding text. The inverse of this hash is needed for decoding messages in Morse code. Also needed for decoding is the key value pair "...---..."=>"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"}


              One more hash is needed to deal with cases where the message "sos" (or "SOS"--Morse code is case insensitive), or "sos" followed by a punctuation character (e.g., "sos!") is to be encoded.1 See the Wiki.



              SOS_WITH_PUNCTUATION = PUNCTUATION.each_with_object({}) { |(k,v),h|
              h["sos#{k}"] = "...---... #{v}" }.merge('sos'=>"...---...")
              #=> {"sos."=>"...---... .-.-.-", "sos,"=>"...---... --..--",
              # "sos?"=>"...---... ..--..", "sos!"=>"...---... -.-.--", "sos"=>"...---..."}


              The encoding and decoding methods follow. encode checks to see if each word in the string is a key in the hash SOS_WITH_PUNCTUATION. If it is, the value of key is the Morse code for the word; else, the word is divided into letters and each letter is translated into Morse code.



              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


              We can now try out these two methods.



              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 It would be simpler to have a pre-processing step that would convert, say, "sos." to "sos .", but when the resulting Morse code were decoded there would be a space between "sos" and ".". I suppose that cryptographers could deal with that, but I've chosen to avoid the insertion of the space.






              share|improve this answer














              I understand from the kata that letters are to be separated by one space and words by three spaces.



              As a first step I will two changes to the hash morse_dict: remove the key ' '; and add key-value pairs for some punctuation characters. The space character key is not needed; the need for punctuation codes is discussed in the 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"=>"-----", "."=>".-.-.-", ","=>"--..--", "?"=>"..--..",
              # "!"=>"-.-.--"}


              I obtained the Morse codes for the punctuation characters from the Morse Code Wiki. Additional punctuation characters could be added if desired.



              The hash ALPHA_TO_MORSE is used in encoding text. The inverse of this hash is needed for decoding messages in Morse code. Also needed for decoding is the key value pair "...---..."=>"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"}


              One more hash is needed to deal with cases where the message "sos" (or "SOS"--Morse code is case insensitive), or "sos" followed by a punctuation character (e.g., "sos!") is to be encoded.1 See the Wiki.



              SOS_WITH_PUNCTUATION = PUNCTUATION.each_with_object({}) { |(k,v),h|
              h["sos#{k}"] = "...---... #{v}" }.merge('sos'=>"...---...")
              #=> {"sos."=>"...---... .-.-.-", "sos,"=>"...---... --..--",
              # "sos?"=>"...---... ..--..", "sos!"=>"...---... -.-.--", "sos"=>"...---..."}


              The encoding and decoding methods follow. encode checks to see if each word in the string is a key in the hash SOS_WITH_PUNCTUATION. If it is, the value of key is the Morse code for the word; else, the word is divided into letters and each letter is translated into Morse code.



              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


              We can now try out these two methods.



              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 It would be simpler to have a pre-processing step that would convert, say, "sos." to "sos .", but when the resulting Morse code were decoded there would be a space between "sos" and ".". I suppose that cryptographers could deal with that, but I've chosen to avoid the insertion of the space.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 15 at 4:39

























              answered Nov 11 at 22:16









              Cary Swoveland

              66.8k53865




              66.8k53865












              • Manipulate the string directly works, however I receive this error rb:60:in block in describe: Expected: "SOS", instead got: nil (Test::Error) I have added SOS to the dictionary and paired with '...---..." but it still returns nil
                – Floroz
                Nov 12 at 11:36












              • What is not clear in "dividing into an array" is: you .split your string morse into an array of single morse word, then iterate over the single word, then I don't understand exactly the next iteration when you .join the value of MORSE_TO_ALPHA.
                – Floroz
                Nov 12 at 11:43












              • Floors, I apologize for not replying to your comments earlier. I somehow missed them. It’s late now so I’ll look into the problems you mention tomorrow.
                – Cary Swoveland
                Nov 13 at 9:19










              • Thank you Cary, I have actually managed to get past the issue by inserting the "SOS" in the dictionary manually and added an if statement just to ensure I could pass the test, and incurred in another error using the different versions of your code as it does not encode back the punctuation (".,!?").
                – Floroz
                Nov 13 at 14:12












              • Floroz, I've edited my answer.
                – Cary Swoveland
                Nov 15 at 4:34


















              • Manipulate the string directly works, however I receive this error rb:60:in block in describe: Expected: "SOS", instead got: nil (Test::Error) I have added SOS to the dictionary and paired with '...---..." but it still returns nil
                – Floroz
                Nov 12 at 11:36












              • What is not clear in "dividing into an array" is: you .split your string morse into an array of single morse word, then iterate over the single word, then I don't understand exactly the next iteration when you .join the value of MORSE_TO_ALPHA.
                – Floroz
                Nov 12 at 11:43












              • Floors, I apologize for not replying to your comments earlier. I somehow missed them. It’s late now so I’ll look into the problems you mention tomorrow.
                – Cary Swoveland
                Nov 13 at 9:19










              • Thank you Cary, I have actually managed to get past the issue by inserting the "SOS" in the dictionary manually and added an if statement just to ensure I could pass the test, and incurred in another error using the different versions of your code as it does not encode back the punctuation (".,!?").
                – Floroz
                Nov 13 at 14:12












              • Floroz, I've edited my answer.
                – Cary Swoveland
                Nov 15 at 4:34
















              Manipulate the string directly works, however I receive this error rb:60:in block in describe: Expected: "SOS", instead got: nil (Test::Error) I have added SOS to the dictionary and paired with '...---..." but it still returns nil
              – Floroz
              Nov 12 at 11:36






              Manipulate the string directly works, however I receive this error rb:60:in block in describe: Expected: "SOS", instead got: nil (Test::Error) I have added SOS to the dictionary and paired with '...---..." but it still returns nil
              – Floroz
              Nov 12 at 11:36














              What is not clear in "dividing into an array" is: you .split your string morse into an array of single morse word, then iterate over the single word, then I don't understand exactly the next iteration when you .join the value of MORSE_TO_ALPHA.
              – Floroz
              Nov 12 at 11:43






              What is not clear in "dividing into an array" is: you .split your string morse into an array of single morse word, then iterate over the single word, then I don't understand exactly the next iteration when you .join the value of MORSE_TO_ALPHA.
              – Floroz
              Nov 12 at 11:43














              Floors, I apologize for not replying to your comments earlier. I somehow missed them. It’s late now so I’ll look into the problems you mention tomorrow.
              – Cary Swoveland
              Nov 13 at 9:19




              Floors, I apologize for not replying to your comments earlier. I somehow missed them. It’s late now so I’ll look into the problems you mention tomorrow.
              – Cary Swoveland
              Nov 13 at 9:19












              Thank you Cary, I have actually managed to get past the issue by inserting the "SOS" in the dictionary manually and added an if statement just to ensure I could pass the test, and incurred in another error using the different versions of your code as it does not encode back the punctuation (".,!?").
              – Floroz
              Nov 13 at 14:12






              Thank you Cary, I have actually managed to get past the issue by inserting the "SOS" in the dictionary manually and added an if statement just to ensure I could pass the test, and incurred in another error using the different versions of your code as it does not encode back the punctuation (".,!?").
              – Floroz
              Nov 13 at 14:12














              Floroz, I've edited my answer.
              – Cary Swoveland
              Nov 15 at 4:34




              Floroz, I've edited my answer.
              – Cary Swoveland
              Nov 15 at 4:34












              up vote
              1
              down vote













              Using Hash#key without replacing the array, rather creating a new one (use map! for replacement):



              array = [1,2,3,4,5]    
              hash = {a: 4, b: 7, c: 3}

              array.map { |el| hash.key(el) }
              # => [nil, nil, :c, :a, nil]


              You may want to think about using Hash#invert and simply referencing the elements by keys for performance reasons as Hash#key is O(n) while Hash# is 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]





              share|improve this answer



























                up vote
                1
                down vote













                Using Hash#key without replacing the array, rather creating a new one (use map! for replacement):



                array = [1,2,3,4,5]    
                hash = {a: 4, b: 7, c: 3}

                array.map { |el| hash.key(el) }
                # => [nil, nil, :c, :a, nil]


                You may want to think about using Hash#invert and simply referencing the elements by keys for performance reasons as Hash#key is O(n) while Hash# is 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]





                share|improve this answer

























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Using Hash#key without replacing the array, rather creating a new one (use map! for replacement):



                  array = [1,2,3,4,5]    
                  hash = {a: 4, b: 7, c: 3}

                  array.map { |el| hash.key(el) }
                  # => [nil, nil, :c, :a, nil]


                  You may want to think about using Hash#invert and simply referencing the elements by keys for performance reasons as Hash#key is O(n) while Hash# is 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]





                  share|improve this answer














                  Using Hash#key without replacing the array, rather creating a new one (use map! for replacement):



                  array = [1,2,3,4,5]    
                  hash = {a: 4, b: 7, c: 3}

                  array.map { |el| hash.key(el) }
                  # => [nil, nil, :c, :a, nil]


                  You may want to think about using Hash#invert and simply referencing the elements by keys for performance reasons as Hash#key is O(n) while Hash# is 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]






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 11 at 20:06

























                  answered Nov 11 at 19:23









                  Marcin Kołodziej

                  4,067315




                  4,067315






















                      up vote
                      0
                      down vote













                      assuming: arr = 'a b c d', which is not an arr, so please make that 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)





                      share|improve this answer

























                        up vote
                        0
                        down vote













                        assuming: arr = 'a b c d', which is not an arr, so please make that 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)





                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          assuming: arr = 'a b c d', which is not an arr, so please make that 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)





                          share|improve this answer












                          assuming: arr = 'a b c d', which is not an arr, so please make that 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)






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 11 at 19:36









                          awsmsce

                          788




                          788






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252238%2fruby-iterating-over-an-array-and-find-match-in-an-hash-and-replace-the-element-i%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Guess what letter conforming each word

                              Port of Spain

                              Run scheduled task as local user group (not BUILTIN)