【问题标题】:Ruby refactoring a hash loop method returnRuby 重构哈希循环方法返回
【发布时间】:2016-02-04 13:10:30
【问题描述】:

我有这样的代码(我经常遇到这种方法签名,我来自 java 的菜鸟):

  def totals
    t = 0
    @data.each do |k, v|
      t += v['totals'].to_i
    end
    t
  end

@data 是散列的散列,每个内部散列值都有一个totals 键。如您所见,我正在总结所有总数。

这可以简化或以不同的风格进行编程(我敢肯定!这毕竟是 RUBY)?为什么我需要实例化t?我不能在没有最后一个条件的情况下直接从每个循环返回 t 吗?

只是感觉不干净! 哦等等!我只记得积木,但我会等待你的答案......

更新:

数据结构如下:

{ typeA: { items: [], totals: "10" },  typeB: { items: [], totals: "23" }}

我正在使用 Rails!因此,如果 Rails 特定的功能可以扩展到 vanilla Ruby 堆栈之外,它们也会很棒!

【问题讨论】:

    标签: ruby-on-rails ruby hash


    【解决方案1】:

    既然你已经表明你正在使用 Ruby on Rails,你可以利用 Active Support 的 Enumerable#sum 方法:

    def totals
      @data.sum {|_,v| v['totals'].to_i }
    end
    

    【讨论】:

    • 接受更好的 API 参考并提到 ActiveSupport 比 Nermin 快 6 秒!艰难的决定!
    • 什么是|_,v|,一些约定这是散列但未使用密钥?
    • @mahatmanich 是的,在块中,您对未使用的变量使用 _ 表示法
    • 它比“典型地”多一点,实际上,语言中甚至还有一些关于它的知识:未使用的局部变量会触发警告,但对于以_开头的变量,此警告会被抑制.此外,多次使用同一个变量作为赋值的参数或目标可能会再次生成警告,如果名称为 _,则该警告将被抑制。
    【解决方案2】:

    在 Rails 5 中,您可以利用Enumerable#pluck

    h.values.pluck(:totals).map(&:to_i).sum
    

    【讨论】:

    • 不利的一面是,这会创建三个临时数组,但有利的一面是它的读数非常好,并且通过多个简单的步骤,它有助于测试。在我看来,如果h 不大,这种方法有很多优点。
    • 不知道您可以将 pluck 与其他对象(即 AR)一起使用。不错,+1
    【解决方案3】:

    使用inject:

    def totals
      @data.inject(0) do |t, (_, v)|
        t + v['totals'].to_i
      end
    end
    

    【讨论】:

      【解决方案4】:

      使用Enumerable sum

      def totals
        @data.sum { |_,v| v['totals'].to_i }
      end
      

      你也可以有不同于 0 的起始值

      def totals(start_value= 0)
        @data.sum(start_value) { |_,v| v['totals'].to_i }
      end
      

      【讨论】:

      • 不需要“编辑:”。此外,我认为编辑的主题并没有真正增加任何有用的东西。简单地提供文档的参考资料——它涵盖了这一点并且本身很有帮助——就足够了。
      【解决方案5】:
      @data.map{ |_, v| v['totals'].to_i }.inject(:+)
      

      甚至更短:

      @data.map{ |_, v| v['totals'].to_i }.sum
      

      【讨论】:

      • 似乎不起作用。它是哈希的哈希 { type: { items: [], totals: XYX } }
      • @mahatmanich 哦,好吧,我的误解。相应地编辑了答案
      • 别忘了建议使用reduce别名inject
      • 因为 inject 来自 SmallTalk,在不同的现代语言中并不常见
      猜你喜欢
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 2013-07-20
      • 1970-01-01
      相关资源
      最近更新 更多