Can somebody help me understand which job the map functions has in this code?
counts = @a.group_by{|i| i}.map{|k,v| [k[0], k[1], v.count]}
@a.group_by{|i| i} is producing an hash, where key/value pairs are Array.
Now #map method takes each pair. k is a key, and v is a value, inside map creating an array [first_entry_of_array,second_entry_of_array,value_array_size]( when key/value both are array). I said key can be an array, as you used k[0], k[1], and Array#[] is the method it is actually.
Example :
a = [ %w(foo bar) ,%W(baz bar), %w(foo bar) ]
a.group_by { |e| e }
# => {["foo", "bar"]=>[["foo", "bar"], ["foo", "bar"]],
# ["baz", "bar"]=>[["baz", "bar"]]}
a.group_by { |e| e }.map{|k,v| [k[0], k[1], v.count]}
# => [["foo", "bar", 2], ["baz", "bar", 1]]
key can be a string also. Then it is inside of #map will be [first_character_of_string,second_character_of_string,value_array_size]. The same reason as with, I doubt key can be a string, as those call are String#[] method call.
Example :
a = %w(foo bar foo baz bar)
a.group_by { |e| e }
# => {"foo"=>["foo", "foo"], "bar"=>["bar", "bar"], "baz"=>["baz"]}
# ^ ^
# key value
a.group_by { |e| e }.map{|k,v| [k[0], k[1], v.count]}
# => [["f", "o", 2], ["b", "a", 2], ["b", "a", 1]]
Basically #map will produce here an array of array.
Straight from the documentation of map :
Returns a new array with the results of running block once for every element in enum.
Here in your example, with the results of running block, means results are being genrated after each iteration, from the block with #map, is [k[0], k[1], v.count].
Straight from the documentation of group_by :
Groups the collection by result of the block. Returns a hash where the keys are the evaluated result from the block and the values are arrays of elements in the collection that correspond to the key.
Hope that helps!