I am aware of the shorthand for map that looks like:
[1, 2, 3, 4].map(&:to_s) > ["1", "2", "3", "4"]
I was told this is shorthand for:
[1, 2, 3, 4].map{|i| i.to_s}
This makes perfect sense. My question is this: It seems there should be an easier way to write:
[1, 2, 3, 4].map{|x| f.call(x)}
for some procedure f. I know the way I just typed isn't all that long to begin with, but I'd contend that neither is the previous example for which the shorthand exists. This example just seems like the complement to the first example: Rather than calling i's to_s method for every i, I wish to call f for every x.
Does such a shorthand exist?
The way the map method works in Ruby is, it takes an enumerable object, (i.e. the object you call it on), and a block. Then, for each of the elements in the enumerable, it executes the block, passing it the current element as an argument. The result of evaluating the block is then used to construct the resulting array.
Each is like a more primitive version of map… It gives you every element so you can work with it, but it doesn't collect the results. Each always returns the original, unchanged object. It returns a new array with the transformed elements.
The Map is obtained in Jubilife City, when visiting the Trainers' School.
Unfortunately this shorthand notation (which calls "Symbol#to_proc") does not have a way to pass arguments to the method or block being called, so you couldn't even do the following:
array_of_strings.map(&:include, 'l') #=> this would fail
BUT, you are in luck because you don't actually need this shortcut to do what you are trying to do. The ampersand can convert a Proc or Lambda into a block, and vice-versa:
my_routine = Proc.new { |str| str.upcase } %w{ one two three }.map &my_routine #=> ['ONE', 'TWO', 'THREE']
Note the lack of the colon before my_routine
. This is because we don't want to convert the :my_routine
symbol into a proc by finding the method and calling .method
on it, rather we want to convert the my_routine
Proc into a block and pass it to map
.
Knowing this, you can even map a native Ruby method:
%w{ one two three }.map &method(:p)
The method
method would take the p
method and convert it into a Proc, and the &
converts it into a block that gets passed to map
. As a result, each item gets printed. This is the equivalent of this:
%w{ one two three }.map { |s| p s }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With