【问题标题】:Get top n elements from ruby array of hash values从哈希值的 ruby​​ 数组中获取前 n 个元素
【发布时间】:2012-06-21 03:11:05
【问题描述】:

嘿,我有一个数组,其中每个元素都是一个包含几个值和一个计数的哈希。

result = [
           {"count" => 3,"name" => "user1"}, 
           {"count" => 10,"name" => "user2"}, 
           {"count" => 10, "user3"},
           {"count" => 2, "user4"}
         ]

我可以按如下方式对数组进行排序:

result = result.sort_by do |r|
  r["count"]
end

现在我希望能够根据计数检索前 n 个条目(不仅仅是第一个(n))有没有一种优雅的方法来做到这一点? 举个例子,让 n = 1 我希望得到一个结果集。

[{"count" => 10,"name" => "user2"}, {"count" => 10, "user3"}]

因为我要求所有得分最高的条目..如果我要求前 2 个最高分我会得到

 [{"count" => 10,"name" => "user2"}, {"count" => 10, "user3"}, {"count" => 3, "user1"}]

【问题讨论】:

    标签: ruby arrays sorting


    【解决方案1】:

    Enumerable#group_by 救援(像往常一样):

    result.group_by { |r| r["count"] }
          .sort_by  { |k, v| -k }
          .first(2)
          .map(&:last)
          .flatten
    

    大部分工作由group_by 完成。 sort_by 简单地排列,以便first(2) 将挑选出你想要的组。然后maplast 将提取您开始使用的计数/名称哈希,最后的flatten 将清理多余的剩余数组。

    【讨论】:

    • 优秀。非常感谢您的帮助。
    【解决方案2】:

    这个解决方案在简洁方面并不优雅,但它具有更好的时间复杂度。 换句话说,对于大量哈希,它应该执行得更快。

    您需要安装 "algorithms" gem 才能使用堆数据结构:

    Heaps 是一种高效的数据结构,当您需要查找组中的最大或最小元素时。如果“n”的值远小于对的总数,则这种特殊类型的堆为optimal

    require 'algorithms'
    def take_highest(result,n)
      max_heap = Containers::Heap.new(result){|x,y| (x["count"] <=> y["count"]) == 1}
      last = max_heap.pop
      count = 0
      highest = [last]
      loop do   
        top = max_heap.pop
        break if top.nil?
        count += (top["count"] == last["count"] ? 0 : 1)
        break if count == n
        highest << top
        last = top
      end
      highest
    end
    

    【讨论】:

      【解决方案3】:
      new_result = result.
        sort_by { |r| -r["count"] }.
        chunk { |r| r["count"] }.
        take(2).
        flat_map(&:last)
      
      #=> [{"count"=>10, "name"=>"user3"}, 
      #    {"count"=>10, "name"=>"user2"}, 
      #    {"count"=> 3  "name"=>"user1"}]
      

      【讨论】:

      • tokland a.k.a Arnau Sánchez 是迄今为止我在 SO 上找到的最好的 ROR 开发人员之一。 :) 您的回答帮助我使用 ruby​​ 哈希获得了预期的结果。谢谢。
      【解决方案4】:

      从 Ruby 2.2.0 开始,max_by 需要一个额外的参数,让您可以请求一定数量的顶级元素,而不仅仅是获取一个。使用这个,我们可以改进mu is too short的答案

      result = [
                 {count: 3, name: 'user1'},
                 {count: 10, name: 'user2'},
                 {count: 10, name: 'user3'},
                 {count: 2, name: 'user4'}
               ]
      p result.group_by { |r| r[:count] }
            .max_by(2, &:first)
            .flat_map(&:last)
            .sort_by { |r| -r[:count] }
      # => [{:count=>10, :name=>"user2"}, {:count=>10, :name=>"user3"}, {:count=>3, :name=>"user1"}]
      

      文档没有说明max_by 返回的数组是否已排序。如果结果是真的,我们可以在最后一步使用reverse 而不是排序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-15
        • 2021-12-15
        • 2014-04-14
        • 1970-01-01
        • 2011-04-12
        • 2016-04-25
        • 2018-02-04
        相关资源
        最近更新 更多