Reputation: 525
I have a method that I want to use to replace characters in a string:
def complexity_level_two
replacements = {
'i' => 'eye', 'e' => 'eei',
'a' => 'aya', 'o' => 'oha'}
word = "Cocoa!55"
word_arr = word.split('')
results = []
word_arr.each { |char|
if replacements[char] != nil
results.push(char.to_s.gsub!(replacements[char]))
else
results.push(char)
end
}
end
My desired output for the string should be: Cohacohaaya!55
However when I run this method, it will not replace the characters and only outputs the string:
C
o
c
o
a
!
5
5
What am I doing wrong that makes this method not replace the correct characters inside of the string to match that in the hash
? How can I fix this to get the desired output?
Upvotes: 19
Views: 44221
Reputation: 9497
Define your method with word and subs parameters:
def char_replacer word, subs
word.chars.map { |c| subs.key?(c) ? subs[c] : c }.join
end
Here we've used the ternary operator which is essentially an if-else expression in a more compact form. Key methods to note are String#chars
, Array#map
, Hash#key?
, see ruby-docs for more info on these. Now with this all set up, you can call your method passing a word string and the subs hash of your choosing.
my_subs = { 'i' => 'eye', 'e' => 'eei','a' => 'aya', 'o' => 'oha' }
my_word = "Cocoa!55"
char_replacer my_word, my_subs #=> "Cohacohaaya!55"
my_subs = { 'a' => 'p', 'e' => 'c' }
my_word = "Cocoa!55"
char_replacer my_word, my_subs #=> "Cocop!55"
Upvotes: 2
Reputation: 54
you can try to do this:
my_subs = { 'i' => 'eye', 'e' => 'eei','a' => 'aya', 'o' => 'oha' }
my_word = "Cocoa!55"
my_word.split('').map{|i| my_subs[i] || i}.join
=> "Cohacohaaya!55"
Upvotes: 1
Reputation: 110675
replacements = { 'i' => 'eye', 'e' => 'eei', 'a' => 'aya', 'o' => 'oha' }.
tap { |h| h.default_proc = ->(h,k) { k } }
"Cocoa!55".gsub(/./, replacements)
#=> "Cohacohaaya!55"
See Hash#default_proc= and Object#tap.
gsub
examines each character of the string. If replacements
has that character as a key, the character is replaced with the value of that key in replacements
; else (because of the default proc), the character is replaced with itself (that is, left unchanged).
Another way would be to use Hash#fetch:
replacements = { 'i' => 'eye', 'e' => 'eei', 'a' => 'aya', 'o' => 'oha' }
"Cocoa!55".gsub(/./) { |s| replacements.fetch(s) { |c| c } }
#=> "Cohacohaaya!55"
which, for Ruby v2.2+ (when Object#itself made its debut), can be written
"Cocoa!55".gsub(/./) { |s| replacements.fetch(s, &:itself) }
Upvotes: 1
Reputation: 121000
replacements = {
'i' => 'eye', 'e' => 'eei',
'a' => 'aya', 'o' => 'oha'}
word = "Cocoa!55"
word.gsub(Regexp.union(replacements.keys), replacements)
#⇒ "Cohacohaaya!55"
Regexp::union
, String#gsub
with hash.
Upvotes: 36