【问题标题】:Find N objects in Array which have the max value in a property using Ruby使用Ruby在数组中查找具有最大值的N个对象
【发布时间】:2013-11-06 05:22:07
【问题描述】:

我有一个对象数组,其中一个字段是这些对象的“分数”。

我知道如何获取具有最大值的对象:

array.max_by do |element|
  element.score
end

但是我如何获得得分最高的 N 个(例如 3 个)对象(有序)?考虑到数组的元素可能少于 N 个。

已编辑:

所以,例如:

[{score:10}, {score:5}, {score:7}, {score:8}] 和 N=3

应该返回:[{score:10}, {score:8}, {score:7}]

【问题讨论】:

    标签: ruby arrays sorting find


    【解决方案1】:

    这是一种方法:

    max = arr.max_by{|e| e.score}
    max_all = arr.find_all{|e| e.score==max}.first(3)
    

    更新

    ar = [{score:10}, {score:5}, {score:7}, {score:8}]
    p ar.sort_by{|e| -e[:score]}.first(3)
    # => [{:score=>10}, {:score=>8}, {:score=>7}]
    

    【讨论】:

    • 使用这种方法,如果数组包含 [{ score: 10}, { score: 5}, {score: 9}, {score: 4}],它只会返回 {score:10 } 对?我需要得分最高的前 N ​​个对象。我已经编辑了我的问题以使其更清楚。
    • @HommerSmith 您应该首先提及.. :) 现在您的最后一次编辑..表明您应该接受 sawa 的 回答... :)
    • 感谢 Arup Rakshit。我有一个问题,-e[:score] 中的“-”是什么?
    • @HommerSmith 否则,您需要使用reverse 方法,但- 首先要这样做..
    • 我认为如果你实现自己的排序,它会更有效率。数组的其余部分不需要排序。如果您使用的是冒泡排序,您只需比较所有元素与最高的 3(或其他固定的低数字)。如果要进行合并排序,则只需合并每个列表的前 3 个长度超过 3 的列表。我认为无论哪种情况,这基本上都会使您的性能从 O(n log n) 或更差降至O(n)。
    【解决方案2】:

    我认为@ArupRakshit 的答案是正确的,不过我会稍微修改一下。

    max = arr.max_by{|i| i.score}
    max_all = arr.find_all{|i| i.score==max}
    

    max_all = arr.select{|i| i.score == max}
    

    这是因为@HommerSmith 提到的输出没有固定数量,它可能是3或更少或更多,我们只需要找到最大字符串和所有长度相等的字符串

    【讨论】:

      【解决方案3】:

      在 Ruby 2.2.0 中,Enumerable#max_by 可以接受一个可选的整数参数,使其返回条目数组而不是单个条目,因此这段代码有效:

      records = [{score:10}, {score:5}, {score:7}, {score:8}]
      p records.max_by(3) { |n| n[:score] }.sort_by { |n| -n[:score] }
      # [{:score=>10}, {:score=>8}, {:score=>7}]
      

      max_by 的文档并没有给我们任何关于返回数组将如何排序的保证,所以我们必须自己对它进行排序,这有点可悲。

      这个答案并不比 Arup 的答案好多少,除了可能的效率提升,因为 Ruby 解释器不需要对整个列表进行排序,如果你的列表很大,这将是一个很大的好处。

      【讨论】:

        猜你喜欢
        • 2014-05-07
        • 2019-02-24
        • 2014-06-13
        • 2017-02-20
        • 2019-12-16
        • 1970-01-01
        • 1970-01-01
        • 2021-12-06
        • 1970-01-01
        相关资源
        最近更新 更多