Alfatah Kader
Alfatah Kader

Reputation: 133

How do I convert a word to phonetic alphabet in Ruby?

I am trying write a code to convert a word into phonetic alphabet. The desired return value should be something like this:

# >> Type your name and I will convert it to Phonetic Alphabets!
Kevin
# >> Kilo Echo Victor India November

I wrote a hash.

puts "Type your name and I will convert it to Phonetic Alphabets!"
name = gets.chomp
nato_keys =  {
    "A": "Alpha", "B": "Bravo",   "C": "Charlie",
    "D": "Delta",  "E": "Echo",    "F": "Foxtrot",
    "G": "Golf",   "H": "Hotel",   "I": "India",
    "J": "Juliett","K": "Kilo",    "L": "Lima",
    "M": "Mike",   "N": "November","O": "Oscar",
    "P": "Papa",   "Q": "Quebec",  "R": "Romeo",
    "S": "Sierra", "T": "Tango",   "U": "Uniform",
    "V": "Victor", "W": "Whiskey", "X": "X-ray",
    "Y": "Yankee", "Z": "Zulu"
  }

def nato()
    puts name.nato_keys.upcase().join(" ")
end

I have an issue with my method as it triggers an error.

Upvotes: 0

Views: 324

Answers (6)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230366

Since no one mentioned it, here's a solution with values_at (this assumes string keys in the substitutions hash, as they should be).

str = "Kevin"
nato_keys.values_at(*str.upcase.chars).join(' ')

Upvotes: 4

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

I would start with preparing more robust hash to transform

transform =
  nato_keys.
  flat_map do |k, v|
    v = v + ' '
    [[k.to_s, v], [k.to_s.downcase, v]]
  end.
  to_h.
  tap { |h| h.default_proc = ->(h, k) { h[k] = k } }

Now you might transform your words as easy as:

"Kevin".gsub(/./, transform).strip
#⇒ "Kilo Echo Victor India November"

Upvotes: -1

sawa
sawa

Reputation: 168121

As Cary Swoveland says, the hash nato_keys, which really does not make sense, has to be converted to one that makes sense:

nato_keys.transform_keys!(&:to_s)

Given:

name = "Kevin"

then,

name.gsub(/(\A)?./){"#{" " unless $1}#{nato_keys[$&.upcase]}"}
# => "Kilo Echo Victor India November"

Upvotes: 0

Tom
Tom

Reputation: 1320

name.upcase.chars.map(&:intern).map(&nato_keys).join(' ')

First we upcase the entire string. We then split the string into each individual char and turn each into a symbol. Then we can map over the chars sending them one at a time to the nato_keys element reference [], returning the phonetic word, and converting the name. Finally, join them with spaces to format the new string.

EDIT: When using Hash element references we can call the Hash itself.

Upvotes: 0

Cary Swoveland
Cary Swoveland

Reputation: 110685

Assuming the number of words to converted is more than 26 it makes sense to prepare the appropriate hash before doing any conversions.

H = nato_keys.transform_keys(&:to_s)
  #=> {"A"=>"Alpha", "B"=>"Bravo",..., "Z"=>"Zulu"}

word = gets.chomp

Supose

word = "Kevin"

Then

word.upcase.each_char.map { |c| H[c] }.join(' ')
  #=> "Kilo Echo Victor India November"

Upvotes: 3

kiddorails
kiddorails

Reputation: 13014

You would want to do this:

name.chars.map { |x| nato_keys[x.upcase.to_sym] }.join(' ')

This name.chars give the enumeration with each character of the string name, map iterates on each character and transforms it to the instruction in the block.

block { |x| nato_keys[x.upcase.to_sym] }, picks the relevant mapping for the character, but before that, it converts the key to uppercase and symbol(because in your nato_keys, keys are symbols). 'a' will become :A.

After the block manipulation, we join the result with ' ' to give resultant string.

Upvotes: 0

Related Questions