Menu
CoddyTech

sort_by、min_by、max_by

CoddyのRubyジャーニー「ロジックとフロー」セクションの一部。レッスン 26/56。

すでに sort、min、max についてはご存知でしょう。_by バージョンを使用すると、何を比較するかを制御できるため、構造化データのソートに最適です。

sort_by はブロックを受け取ります。ブロックは各要素を比較するための値を返します:

words = ["banana", "hi", "hello"]
by_length = words.sort_by { |w| w.length }
puts by_length.inspect   # ["hi", "hello", "banana"]

降順にするには、比較キーを反転させる(数値の場合は -w.length)、または結果に対して reverse を呼び出します。

min_by と max_by は、ブロックの評価値が最小/最大となる単一の要素を返します:

people = [
  { name: "Ada",   age: 36 },
  { name: "Bob",   age: 22 },
  { name: "Cara",  age: 41 }
]

youngest = people.min_by { |p| p[:age] }
oldest   = people.max_by { |p| p[:age] }
puts youngest[:name]   # Bob
puts oldest[:name]     # Cara

次の短縮形も動作します: words.sort_by(&:length)。

challenge icon

チャレンジ

中級

配列 products が与えられています。各要素は :name、:price、および :quantity を持つハッシュです。各商品の在庫価値は price * quantity です。

次の3行を出力してください:

  1. 在庫価値の降順でソートされた名前を、, で連結したもの(派生した値に対して sort_by を使用してください)
  2. 価格が 5 未満の商品の中で、最も数量が多い商品の名前(フィルタリングされたリストに対して max_by を使用してください)
  3. 数量が 10 以上の商品の中で、最も安い商品の名前(フィルタリングされたリストに対して min_by を使用してください)

デフォルトの配列の場合、出力は次のようになります:

cheese, milk, bread, apple
bread
bread

自分で試してみよう

products = [
  { name: "milk",   price: 3, quantity:  8 },
  { name: "apple",  price: 1, quantity:  4 },
  { name: "cheese", price: 5, quantity:  6 },
  { name: "bread",  price: 2, quantity: 12 }
]

# TODO: 在庫価値で降順ソート; 数量の最大値を取得 (価格 < 5); 価格の最小値を取得 (数量 >= 10)
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

ロジックとフローのすべてのレッスン

自分で練習してみよう: Rubyオンラインコンパイラ