-2

I’m trying to get a better grasp on writing in Ruby and working with Hash tables and their values.

1. Say you have a hash:

‘FOO’= {‘baz’ => [1,2,3,4,5]}

Goal: convert each value into a string in the ‘Ruby’ way.

I’ve come across multiple examples of using .each eg.

FOO.each = { |k,v| FOO[k] = v.to_s } 

However this renders an array encapsulated in a string. Eg. "[1,2,3,4,5]" where it should be ["1", "2", "3", "4", "5"].

2. When type casting is performed on a Hash that’s holds an array of values, is the result a new array? Or simply a change in type of value (eg. 1 becomes “1” when .to_s is applied (say the value was placed through a each enumerator like above).

An explanation is greatly appreciated. New to Ruby.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
thesayhey
  • 938
  • 3
  • 17
  • 38

2 Answers2

3

In the each block, k and v are the key value pair. In your case, 'baz' is key and [1,2,3,4,5] is value. Since you're doing v.to_s, it converts the whole array to string and not the individual values.

You can do something like this to achieve what you want.

foo = { 'baz' => [1,2,3,4,5] }
foo.each { |k, v| foo[k] = v.map(&:to_s) }
Anurag Aryan
  • 611
  • 6
  • 16
  • 4
    Of course, this will fail when `v` is _not_ an array. :shrug: But let this be OP's homework :) – Sergio Tulentsev Jan 12 '18 at 13:55
  • 1. Does the `map` portion iterate over each value and replace the original value types? 2. `&:s` ? Shortcut for applying string to each value? – thesayhey Jan 12 '18 at 13:56
  • 1
    @thesayhey Yes map loops over each element of array and creates a new array containing the values returned by the block. – Anurag Aryan Jan 12 '18 at 14:00
  • 1
    @thesayhey You can go through [this](https://stackoverflow.com/questions/1217088/what-does-mapname-mean-in-ruby) to understand `&:`. It's explained well and is one of the thing you'll see a lot in ruby. – Anurag Aryan Jan 12 '18 at 14:01
  • Much appreciated. Will spend some time. Def trying to nail down fundamentals and Ruby best practice. Thanks Anurag! – thesayhey Jan 12 '18 at 14:03
1

You can use Hash#transform_values:

foo = { 'baz' => [1, 2, 3, 4, 5] }                                     
foo.transform_values { |v| v.map(&:to_s) } #=> {"baz"=>["1", "2", "3", "4", "5"]} 
Sagar Pandya
  • 9,323
  • 2
  • 24
  • 35