其他Ruby Map速记表示法

trh*_*178 23 ruby map shorthand

我知道地图的简写如下:

[1, 2, 3, 4].map(&:to_s)
> ["1", "2", "3", "4"]
Run Code Online (Sandbox Code Playgroud)

我被告知这是简写:

[1, 2, 3, 4].map{|i| i.to_s}
Run Code Online (Sandbox Code Playgroud)

这很有道理.我的问题是:似乎应该有一种更简单的方式来编写:

[1, 2, 3, 4].map{|x| f.call(x)} 
Run Code Online (Sandbox Code Playgroud)

对于某些程序f.我知道我输入的方式并不是那么长,但是我认为前面的例子都不是速记存在的.这个例子似乎是第一个例子的补充:我不想为每个i调用i的to_s方法,我希望为每个x调用f.

这样的速记是否存在?

cor*_*ard 46

不幸的是,这种简写符号(称为"Symbol#to_proc")没有办法将参数传递给被调用的方法或块,因此您甚至无法执行以下操作:

array_of_strings.map(&:include, 'l') #=> this would fail
Run Code Online (Sandbox Code Playgroud)

但是,你很幸运,因为你实际上并不需要这个快捷方式来做你想做的事情.&符号可以将Proc或Lambda转换为块,反之亦然:

my_routine = Proc.new { |str| str.upcase }
%w{ one two three }.map &my_routine #=> ['ONE', 'TWO', 'THREE']
Run Code Online (Sandbox Code Playgroud)

注意之前缺少结肠my_routine.这是因为我们不想:my_routine通过查找方法并调用.method它来将符号转换为proc ,而是希望将my_routineProc转换为块并将其传递给map.

知道了这一点,你甚至可以映射一个原生的Ruby方法:

%w{ one two three }.map &method(:p)
Run Code Online (Sandbox Code Playgroud)

该method方法将采用该p方法并将其转换为Proc,并将其&转换为传递给的块map.结果,每个项目都被打印出来.这相当于:

%w{ one two three }.map { |s| p s }
Run Code Online (Sandbox Code Playgroud)

  • @DaveNewton我不认为你理解这个问题.看来他已经有一个现有的Proc或Lambda,他在问题中称之为"f".他可以用`array.map(&f)`得到他想要的东西,这实际上是一个比他试过的更短的字符. (5认同)
  • 虽然确实如此,但我不相信OP会认为他/她自己"幸运"必须分别定义块以获得"更短"的"map"调用. (3认同)