Other Ruby Map Shorthand Notation

僤鯓⒐⒋嵵緔 提交于 2019-11-29 10:59:02

问题


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?


回答1:


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 }


来源:https://stackoverflow.com/questions/8793616/other-ruby-map-shorthand-notation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!