【问题标题】:What does the multiplication symbol :* do?乘法符号 :* 有什么作用?
【发布时间】:2013-02-20 21:13:46
【问题描述】:

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

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

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

【问题讨论】:

    标签: ruby ruby-1.9 enumerable


    【解决方案1】:

    inject() 可以带一个块或一个符号,但map() 总是带一个块。我觉得你的工作map()已经够简洁了。

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

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

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

    【讨论】:

    • 谢谢(+1)!除了显式写出块之外,还有其他方法可以将现有方法(如*)转换为块或过程吗? map(to_proc(*)) 之类的东西?
    • 好吧,您可以使用:*.to_proc 将符号转换为proc,但在这种情况下没有想到如何优雅地使用它。我认为你想要的最重要的东西是经典的 map/reduce:[[1,2], [3,4], [5,6]].map{|a| a.reduce(:*)}.
    • 在回到这个并寻找不同的选项之后,看起来确实 map/reduce 基本上是最接近我想要的解决方案。感谢您的帮助!
    【解决方案2】:

    你可以这样做:

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

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

    问候,

    【讨论】:

      【解决方案3】:

      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"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-17
        • 1970-01-01
        • 2012-12-13
        • 1970-01-01
        • 2013-06-02
        • 1970-01-01
        • 2017-07-24
        相关资源
        最近更新 更多