2012-02-08 56 views
3

紅寶石有Enumerable#maxEnumerable#max_by,我以下面的方式使用max_by在具有相同最大值的多於一個的情況下獲得最大數組

array = [ 
      {:a => 1, :b => 2, :c => 3}, 
      {:a => 3, :b => 2, :c => 4}, 
      {:a => 3, :b => 1, :c => 4} 
     ] 
max_item = array.max_by { |item| item[:b] } 
=> {:b=>2, :c=>3, :a=>1} 

所以它將單個最大值(我認爲第一)返回,即使有2項與相同的最大值。我想實現一個在這種情況下提供這兩個項目的函數。有沒有max_by的其他變體,還是我需要從頭開始編寫這個?

回答

9
array = [ 
      {:a => 1, :b => 2, :c => 3}, 
      {:a => 3, :b => 2, :c => 4}, 
      {:a => 3, :b => 1, :c => 4} 
     ] 

array.group_by{|el| el[:b]}.max.last 
#=>[{:a=>1, :b=>2, :c=>3}, {:a=>3, :b=>2, :c=>4}] 

group_by的作用有點太硬,但它確實交付。

+0

不知道有關'group_by';整齊。 – Chowlett 2012-02-08 15:53:37

+0

我知道'group_by',但無法通過這個邏輯思考..我不得不閱讀這個帖子兩次以獲得邏輯..splendid! – rubyprince 2012-02-08 17:15:41

4

據我所知,沒有這樣的方法。然而,下面應該做什麼?(我已經將其添加到Array只是因爲我在irb工作 - 你可以猴子修補它無論更有意義)

class Array 
    def maxes_by &block 
    max_condition = block.call(max_by(&block)) 
    select {|it| block.call(it) == max_condition} 
    end 
end 

array = [ 
      {:a => 1, :b => 2, :c => 3}, 
      {:a => 3, :b => 2, :c => 4}, 
      {:a => 3, :b => 1, :c => 4} 
     ] 
array.maxes_by{|it| it[:b]} 
# => [{:a=>1, :b=>2, :c=>3}, {:a=>3, :b=>2, :c=>4}] 
+1

您正在爲每個元素+1調用'block'(這可能是個昂貴的操作)兩次,'group_by'絕對是更好的解決方案。 – 2012-02-08 14:38:53

相關問題