Rubyでデータを整理する!初心者でもわかるsortメソッドの使い方10選

Ruby初心者がsortメソッドを使ってデータを整理する方法Ruby
この記事は約12分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

初めてプログラミング言語「Ruby」を学んでみたけれど、データを整理する方法がわからないとお困りの方、この記事を読むと、あなたもRubyでのデータの整理が可能になります。

Rubyには「sortメソッド」という、配列の要素を順番に並べ替えるためのメソッドがあります。

今回は、このsortメソッドの基本的な使い方から応用例まで、初心者でもわかる10の使い方を詳しく解説します。

●Rubyとsortメソッドの基本

Rubyは、人間が直感的に理解しやすい自然なコードを書けるようにデザインされたプログラミング言語です。

そのRubyで、データの並び替えを行う方法の一つが「sortメソッド」です。sortメソッドは配列に対して使用し、配列の要素をある基準に従って並び替えることができます。

●sortメソッドの使い方

sortメソッドの基本的な使い方は非常にシンプルです。

配列オブジェクトに対して.sortを呼び出すだけで、配列の要素をソート(並べ替え)できます。

○サンプルコード1:数値配列のソート

numbers = [5, 3, 8, 1, 4]
sorted_numbers = numbers.sort
puts sorted_numbers # => [1, 3, 4, 5, 8]

このコードでは、数値を要素に持つ配列numbersを作成しています。

次に、この配列に対してsortメソッドを呼び出し、その結果をsorted_numbersに代入しています。

最後にputsを使ってsorted_numbersを出力しています。

出力結果は配列の要素が小さい順に並んだものになります。

○サンプルコード2:文字列配列のソート

words = ["dog", "cat", "elephant", "ant", "bee"]
sorted_words = words.sort
puts sorted_words # => ["ant", "bee", "cat", "dog", "elephant"]

この例では、文字列を要素に持つ配列wordsをソートしています。

文字列の場合、sortメソッドは各文字の辞書順(ASCIIコード順)に基づいて文字列をソートします。

出力結果は辞書順に並んだ配列になります。

○サンプルコード3:大きさ順にソート

sizes = ["M", "XL", "S", "L", "XS"]
sorted_sizes = sizes.sort
puts sorted_sizes # => ["L", "M", "S", "XL", "XS"]

この例では、サイズを表す文字列を要素に持つ配列sizesをソートしています。

sortメソッドを使用した場合、結果は文字列の長さではなく、辞書順にソートされます。

したがって、出力結果は[“L”, “M”, “S”, “XL”, “XS”]となります。

ただ、サイズの文字列を自然な順序(”XS”, “S”, “M”, “L”, “XL”)でソートしたい場合はどうすればよいのでしょうか?

そんな時は、sortメソッドと組み合わせて使う「ブロック」を使うことで、自分の望む基準でソートすることが可能になります。

●sortメソッドとブロック

sortメソッドは「ブロック」を引数として取ることができます。

ブロックは、{}またはdo..endで囲まれたコードの塊を表し、メソッドに追加の動作を伝える役割があります。

sortメソッドの場合、ブロック内で比較したい基準を自分で定義することができます。

○サンプルコード4:sortメソッドとブロックを用いた複雑なソート

sizes = ["M", "XL", "S", "L", "XS"]
size_order = {"XS" => 1, "S" => 2, "M" => 3, "L" => 4, "XL" => 5}
sorted_sizes = sizes.sort do |a, b|
  size_order[a] <=> size_order[b]
end
puts sorted_sizes # => ["XS", "S", "M", "L", "XL"]

このコードでは、先程のサイズを表す文字列を要素に持つ配列sizesを自然な順序でソートする例を紹介しています。

まず、各サイズを自然な順序に対応する数値にマッピングしたハッシュsize_orderを作成します。

そして、sortメソッドにブロックを渡して、このsize_orderを基にサイズの文字列を比較します。

出力結果は自然な順序でソートされたサイズの配列となります。

●sortメソッドの応用例

ここからは、さらに高度なsortメソッドの使い方をいくつか紹介します。

○サンプルコード5:オブジェクトの配列のソート

students = [
  {name: "Yamada", score: 70},
  {name: "Tanaka", score: 90},
  {name: "Suzuki", score: 80}
]
sorted_students = students.sort do |a, b|
  a[:score] <=> b[:score]
end
puts sorted_students 
# => [{:name=>"Yamada", :score=>70}, {:name=>"Suzuki", :score=>80}, {:name=>"Tanaka", :score=>90}]

この例では、ハッシュの配列studentsをソートしています。

各ハッシュは学生の名前とスコアを表しています。sortメソッドにブロックを渡すことで、スコアに基づいて学生をソートします。

出力結果はスコアの低い順にソートされた学生のリストとなります。

○サンプルコード6:大文字小文字を無視したソート

words = ["ruby", "Java", "PYTHON", "c++", "JavaScript"]
sorted_words = words.sort do |a, b|
  a.downcase <=> b.downcase
end
puts sorted_words # => ["c++", "Java", "JavaScript", "PYTHON", "ruby"]

このコードでは、大文字と小文字を無視して文字列の配列をソートする例を紹介しています。

ソートする前のwords配列には、大小文字が混在したプログラミング言語の名前が含まれています。

しかし、sortメソッドのブロック内でdowncaseメソッドを使用して、大文字を小文字に変換します。

このようにすることで、大文字と小文字を無視して文字列をソートします。

結果として、アルファベット順にソートされたプログラミング言語の名前が出力されます。

○サンプルコード7:ハッシュのソート

scores = {"Yamada" => 70, "Tanaka" => 90, "Suzuki" => 80}
sorted_scores = scores.sort do |a, b|
  a[1] <=> b[1]
end.to_h
puts sorted_scores # => {"Yamada"=>70, "Suzuki"=>80, "Tanaka"=>90}

この例では、ハッシュのソート方法を紹介しています。

キーと値のペアを持つハッシュscoresをソートするために、sortメソッドを使用します。

sortメソッドのブロック内では、a[1]b[1]を用いて値(スコア)に基づいてハッシュをソートします。

結果として、スコアの低い順にソートされたハッシュが出力されます。

○サンプルコード8:配列内の特定の条件でソート

products = [{"name" => "Apple", "price" => 200}, {"name" => "Banana", "price" => 100}, {"name" => "Cherry", "price" => 300}]
sorted_products = products.sort do |a, b|
  a["price"] <=> b["price"]
end
puts sorted_products # => [{"name"=>"Banana", "price"=>100}, {"name"=>"Apple", "price"=>200}, {"name"=>"Cherry", "price"=>300}]

このコードでは、ハッシュの配列を特定の条件でソートする方法を示しています。

この例では、商品名と価格を持つハッシュの配列を扱っています。

ソートの条件として、「価格」のキーに対応する値を用いています。

それぞれのハッシュ内で “price” に対応する値を比較し、その結果に基づいて配列全体をソートします。

実行結果は、価格が低い順(つまり、100, 200, 300)に商品が並んだ配列になります。

○サンプルコード9:ソート結果の逆順出力

numbers = [5, 3, 8, 1, 4]
sorted_numbers = numbers.sort.reverse
puts sorted_numbers # => [8, 5, 4, 3, 1]

このコードでは、配列をソートした後にその結果を逆順にする方法を紹介しています。

sortメソッドに続けてreverseメソッドを用いることで、ソート結果を逆転させます。

この例では、数字の配列を降順(大きい順)にソートしています。

実行結果として、最大の数値から最小の数値へと順序付けられた配列が出力されます。

○サンプルコード10:独自の比較関数を定義してソート

numbers = [5, 3, 8, 1, 4]
sorted_numbers = numbers.sort do |a, b|
  b <=> a
end
puts sorted_numbers # => [8, 5, 4, 3, 1]

このコードでは、自分自身で比較関数を定義し、その関数に基づいて配列をソートする方法を表しています。

ここでは、sortメソッド内にブロックを渡し、そのブロック内で比較関数を定義しています。

ブロック内のコード b <=> a は、通常の比較とは逆の順序で比較を行うことを意味します。

これにより、数字の配列が降順(大きい順)にソートされます。

実行結果は、最大の数値から最小の数値へと順序付けられた配列が出力されます。

●注意点と対処法

1つ目の注意点は、「比較可能なデータ型」に関するものです。

sortメソッドは、配列内のすべての要素が互いに比較可能であることを前提としています。

つまり、文字列と数値のような異なるデータ型を含む配列をソートしようとすると、エラーが発生します。

mixed_data = ["apple", 2, "banana"]
sorted_data = mixed_data.sort # => エラー!

この問題を解決するには、全ての要素が比較可能なデータ型であることを確認することが重要です。

あるいは、全ての要素を互いに比較可能な型に変換することも考えられます。

2つ目の注意点は、「破壊的なメソッドと非破壊的なメソッド」の違いです。

Rubyには、オブジェクト自体を変更する「破壊的なメソッド」(sort!など)と、新しいオブジェクトを生成して元のオブジェクトは変更しない「非破壊的なメソッド」(sortなど)があります。

sortメソッドは非破壊的で、元の配列は変更されず新しい配列が生成されます。

一方、sort!メソッドは破壊的で、元の配列自体が変更されます。

これらの違いを理解することは、予期せぬバグを避けるために非常に重要です。

元のデータを保持したままソートした結果を利用したい場合はsortメソッドを、元のデータをソートした状態に更新したい場合はsort!メソッドを使用することで適切に対応できます。

3つ目の注意点は、「ブロックを渡すことでのカスタム比較」です。

sortメソッドにブロックを渡すことで、自分だけの比較ルールを定義することが可能です。

ただし、ブロック内で行われる比較が常に一貫した結果を返すことが重要です。

一貫性のない比較ルールを使用すると、予期せぬ結果やエラーが発生する可能性があります。

●カスタマイズの方法

Rubyのsortメソッドは高度にカスタマイズ可能です。

特に、ソートの比較処理を自分で定義したい場合に便利です。

ブロックを利用して、特定のルールに従ったソートを実現することができます。

このコードでは、文字列の長さを基準にソートするカスタム比較を作っています。

この例では、文字列の長さが短い順に配列をソートします。

fruits = ["apple", "banana", "kiwi", "cherry"]
sorted_fruits = fruits.sort { |a, b| a.length <=> b.length }
puts sorted_fruits

このコードを実行すると、「kiwi」、「apple」、「cherry」、「banana」という順番で出力されます。

つまり、文字列の長さが短い順にソートされているのです。

ここで、「<=>」演算子は「スペースシップ演算子」とも呼ばれ、2つの値を比較して、左側が小さい場合は-1、等しい場合は0、大きい場合は1を返します。

また、Rubyのsortメソッドは、ブロック内での比較結果として-1、0、1のいずれかを返すことを期待しています。

これらの値は、それぞれ「aがbより小さい」、「aとbが等しい」、「aがbより大きい」を意味します。

このように、sortメソッドを使うと、Rubyでデータの整理を簡単に、かつ自由度高く行うことが可能になります。

ただし、ブロック内の比較ルールが一貫していることが重要で、一貫性がないと予期せぬ結果が得られることがあります。

そのため、カスタム比較を作る際は、比較ルールが全てのデータに対して正しく適用されることを確認することが必要です。

まとめ

今回の記事では、Rubyのsortメソッドを使用してデータを整理する方法を初心者の方でも理解できるように詳細に解説しました。

sortメソッドは非常に強力であり、データの並べ替えを効率的に行うことができます。

まずは、基本的な使い方から始めました。

sortメソッドを単純に配列に適用することで、データが昇順に並び替えられることを見ました。

また、sortメソッドにブロックを渡すことで、カスタムの比較を行い、自由なソートルールを定義することができます。

文字列の長さでソートする例を見てきましたが、実際の問題ではさまざまなソートルールを自由に定義して使用することができます。

しかし、カスタムの比較ルールを作る際には注意が必要です。

不適切な比較ルールを設定すると、予期せぬ結果を引き起こす可能性があるためです。

この記事を通して、Rubyのsortメソッドが初心者にも理解しやすいことを実感していただければと思います。

この記事が、あなたのRubyでのデータ整理の旅に役立つ一助になれば幸いです。