乘法符号是什么:*做什么?

时间:2013-02-20 21:13:47

标签: ruby ruby-1.9 enumerable

特别是,使用inject,以下脚本,

  • 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>'

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

3 个答案:

答案 0 :(得分:5)

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

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

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

[[1,2], [3,4], [5,6]].map{|a| a.reduce(:*)}

答案 1 :(得分:2)

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

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

在这里,您可以看到注入的工作原理Enumerable Doc's

此致

答案 2 :(得分: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"