【问题标题】:Ruby Array of Arrays Group and Count by ValuesRuby数组的数组分组和按值计数
【发布时间】:2016-06-28 04:29:03
【问题描述】:

我正在尝试获取一个 Ruby 数组数组并将其分组以计算其值。

数组有一个月份和一个布尔值:

array = [["June", false], ["June", false], ["June", false], ["October", false]]

我想以一个新的数组结尾,让我知道每个月有多少假与真。

示例:(其中Array中的第一项是月份,第二项是false的计数,第三项是true的计数)

new_array = [["June", 3, 0]], ["October", 1, 0]]

【问题讨论】:

    标签: arrays ruby


    【解决方案1】:

    使用Enumerable#group_by

    Array.group_by { |month, b| month }.map{ |month, xs|
      [month,
       xs.count {|_, b| !b},  # false
       xs.count {|_, b| b}]   # true
    }
    # => [["June", 3, 0], ["October", 1, 0]]
    

    【讨论】:

    • Enumerable#group_by 返回一个哈希,而不是一个数组。
    • @Jordan,这就是我用map 调用链接返回值的原因。 (并且需要进一步处理以计数truefalses)
    • 啊,你做到了。我的错。
    • 很好...希望继续学习并 100% 了解您是如何做到的 :)
    【解决方案2】:
    array.map(&:dup) # we’ll mutate it
         .group_by(&:shift)
         .flat_map { |k, v| [k, v.partition { |e| e }.map(&:count)] }
    #⇒ [ ['June', [0, 3] ], ['October', [0, 1] ] ] 
    

    【讨论】:

      【解决方案3】:

      Enumerable#group_by 是一个有用的工具,但在这种情况下它不是最好的。

      如果我们从一个默认值为[0, 0] 的哈希开始,我们可以(几乎)做任何事情——查找月份(或获取新月份的默认值)并将相应的索引加 1 (@987654323 @ 为假,1 为真)——一步完成:

      array = [["June", false], ["June", false], ["June", false], ["October", false]]
      
      hsh = Hash.new {|h,k| h[k] = [0,0] }
      array.each {|mo, bool| hsh[mo][bool ? 1 : 0] += 1 }
      
      p hsh.map(&:flatten)
      # => [["June", 3, 0], ["October", 1, 0]]
      

      【讨论】:

      • 这也有效。为什么 Enumerable#group_by 更好?
      • 对于group_by,我们必须对数据进行四次迭代:一次进行分组,一次计算trues,再次计算falses,然后再次计算将哈希转换为数组。使用上述方法,我们只需要迭代两次:一次进行计数,一次将其转换为数组。
      【解决方案4】:

      我认为这对于reduce 操作来说是一个很好的用例。你会做这样的事情:

      arr = [["June", false], ["June", false], ["June", false], ["October", false]]
      logical_group = Hash.new{|h, k| h[k] = Hash.new(0) }
      
      arr.reduce(logical_group) do |red, ele|
        red[ele.first][:false_count] += 1 unless ele.last
        red[ele.first][:true_count] += 1 if ele.last
        red
      end.reduce([]) do |red, (key, value)|
        red << [key, value[:false_count], value[:true_count]]
        red
      end
      

      【讨论】:

        【解决方案5】:
        Array.group_by {|(Array, boolean)| Array }.map {|Array, match| [Array, match.count] }
        

        【讨论】:

        • 您在发布之前尝试过此代码吗?你知道它不起作用吗?
        • 抛出以下错误:形式参数不能是常量
        猜你喜欢
        • 1970-01-01
        • 2020-11-30
        • 2015-06-30
        • 2017-09-13
        • 1970-01-01
        • 2017-02-23
        • 2015-02-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多