2012-02-08 26 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

+0

私は 'group_by'について知っていましたが、このロジックを考えることができませんでした。私は論理を得るために投稿を2回読む必要がありました。 – rubyprince

4

私の知る限り、このような方法はありません。しかし、次は(私はirbで働いていたという理由だけでArrayにそれを追加しました - 最も理にかなってどこがそれを猿パッチすることができます)行う必要があります

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で 'ブロック'(これは潜在的に高価な操作です)を呼び出しています、 'group_by'は間違いなく良い解決策です。 –

関連する問題