3

特别是,使用注入,以下脚本,

  • puts (1..5).inject {|x, y| x * y}
  • puts (1..5).inject(:*),

两者都有120我预期的输出。

然而,剧本

print [[1,2], [3,4], [5,6]].map {|x, y| x * y}

有输出

[2, 12, 30]

正如预期的那样,但脚本

print [[1,2], [3,4], [5,6]].map(:*)

引发ArgumentError

confused_ruby_map_inject.rb:1:in `map': wrong number of arguments(1 for 0) (ArgumentError)
    from confused_ruby_map_inject.rb:1:in `<main>'

为什么会发生这种情况,有什么作用:*,以及使用第二组脚本实现我正在寻找的结果的最简洁方法是什么?

4

3 回答 3

5

inject()可以带块或符号,但map()总是带块。我认为你的工作map()足够简洁。

:*是乘法方法的符号名称。

更新:我认为你的工作map()很好,但看起来你可能正在寻找的是经典的 map/reduce,即使它实际上更长:

[[1,2], [3,4], [5,6]].map{|a| a.reduce(:*)}
于 2013-02-20T21:26:18.200 回答
2

您可以通过以下方式进行操作:

[[1,2], [3,4], [5,6]].collect{|t| t.inject(:*)}

在这里你可以看到注入是如何工作的Enumerable Doc's

问候,

于 2013-02-20T21:26:37.207 回答
2

inject有特殊的语法;您可以使用&符号接近地图:

print [[1,2], [3,4], [5,6]].map(&:first) #=>[1, 3, 5] #note the ampersand

print [[1,2], [3,4], [5,6]].map(&:*)     #=>in `*': wrong number of arguments(0 for 1) (ArgumentError)

错误是因为*-method需要一个参数(字符串或整数),这不是可选的。这是您在执行时会遇到的错误[1,2].*

演示内容*

p [1,2]*2       #=> [1, 2, 1, 2]
p [1,2]*' and ' #=> "1 and 2"
于 2013-02-20T21:58:48.420 回答