如何将lambda传递给hash.each
,以便重新使用某些代码?
> h = { a: 'b' }
> h.each do |key, value| end
=> {:a=>"b"}
> test = lambda do |key, value| puts "#{key} = #{value}" end
> test.call('a','b')
a = b
> h.each &test
ArgumentError: wrong number of arguments (1 for 2)
from (irb):1:in `block in irb_binding'
from (irb):5:in `each'
from (irb):5
from /Users/jstillwell/.rvm/rubies/ruby-1.9.3-p362/bin/irb:16:in `<main>'
> h.each test
ArgumentError: wrong number of arguments(1 for 0)
from (irb):8:in `each'
from (irb):8
from /Users/jstillwell/.rvm/rubies/ruby-1.9.3-p362/bin/irb:16:in `<main>'
答案 0 :(得分:11)
each
产生块的当前元素,因为lambda需要接受一个参数,而不是两个。在Hash
的情况下,产生的元素是两个元素Array
,第一个元素是键,第二个元素是值。
test = lambda do |el| puts "#{el.first} = #{el.last}" end
h.each &test
# a = b
或者,您可以使用Ruby支持在参数列表中解构bind:
test = lambda do |(k, v)| puts "#{k} = #{v}" end
h.each &test
# a = b
或者,不是使用具有相同参数绑定语义的lambda
作为方法,而是可以使用Proc
,它具有与块相同的参数绑定语义,即它将解包多个参数绑定中的单个Array
参数:
test = proc do |k, v| puts "#{k} = #{v}" end
h.each &test
# a = b
答案 1 :(得分:0)
我仍然觉得这是不一致的语法,我在另一个问题中找到答案(但没有道歉) Inconsistency of arity between Hash.each and lambdas
我把它改为
lambda do |(key, value)|
然后我可以传入
hash.each &test
或者我可以直接用
来调用它test.call([key, value])
如果有人有更好的答案,或者至少有一个简洁的借口,为什么这是必要的。我很乐意给他们分数。
答案 2 :(得分:0)
我遇到过类似的情况,我不想打印,而是在对值进行了一些操作之后返回键-值对...上述解决方案适用于您只想打印的情况,但是当您要打印时,可能会变得棘手您需要返回这些键值对的哈希值。所以我认为这可能会有所帮助
我用它来解决caesar-cipher难题
hash1 = {"a" => 1, "b" => 2, "c" => 3}
test = lambda {|k,v| true ? {k => v+2} : {k => v+1} }
将其映射到哈希之后,它将返回一个哈希数组(这是有趣的地方)
hash2 = hash1.map(&test) # [{"a"=>3}, {"b"=>4}, {"c"=>5}]
我们可以将其转换为红宝石哈希!
hash2.inject(:merge!) # {"a" => 3, "b" => 4, "c" => 5}
宾果!!!对?