传递一个lambda作为一个块
我试图定义一个块,我将使用传递多个范围的每个方法。 而不是重新定义每个范围的块,我想创build一个lamba,并传递lambda:
count = 0 procedure = lambda {|v| map[count+=1]=v} ("A".."K").each procedure ("M".."N").each procedure ("P".."Z").each procedure
但是,我得到以下错误:
ArgumentError:错误的参数个数(1代表0) 来自code.rb:23:在“每个”
任何想法发生了什么?
将&符号( &
)加到参数上,例如:
("A".."K").each &procedure
这表示您将它作为方法的特殊块parameter passing。 否则,它被解释为一个正常的论点。
它也反映了它们在方法本身内部捕获和访问块参数的方式:
# the & here signifies that the special block parameter should be captured # into the variable `procedure` def some_func(foo, bar, &procedure) procedure.call(foo, bar) end some_func(2, 3) {|a, b| a * b } => 6
诀窍在于,如果需要,使用&
告诉Ruby将此参数转换为Proc
,然后使用该对象作为方法的块。 从Ruby 1.9开始,有一个lambda(匿名)函数的快捷方式。 所以,你可以写这样的代码:
(1..5).map &->(x){ x*x } # => [1, 4, 9, 16, 25]
将采取arrays的每个元素并且计算它的力量
它和这个代码一样:
func = ->(x) { x*x } (1..5).map &func
对于Ruby 1.8:
(1..5).map &lambda {|x| x*x} # => [1, 4, 9, 16, 25]
为了解决你的问题,你可以使用Array的方法reduce
( 0
是初始值):
('A'..'K').reduce(0) { |sum,elem| sum + elem.size } # => 11
传递一个lambda函数来reduce
有点棘手,但是匿名块和lambda几乎是一样的。
('A'..'K').reduce(0) { |sum, elem| ->(sum){ sum + 1}.call(sum) } # => 11
或者你可以像这样连接字母:
('A'..'K').reduce(:+) => "ABCDEFGHIJK"
转换为小写:
('A'..'K').map &->(a){ a.downcase } => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]
在方法定义的上下文中,在最后一个参数前加一个“&”符号表示一个方法可能会占用一个块,并给我们一个名称来引用方法体内的这个块。