• WebCamp_インタビュー
    「1カ月頑張ればこの先が見えてくる」地元メディアを立ち上げたママさん
    2017.07.20
  • WebCamp_インタビュー
    「自信の持てるスキルを得たい!」内定辞退した女子大生がプログラミングを学習したワケ。
    2018.04.28
  • WebCamp_インタビュー
    【WebCamp受講生インタビュー】起業準備中にCEOが気がついたプログラミングスキルの重要性とは?
    2017.12.25
  • WebCampPro_インタビュー
    未経験でも寿司職人からWebデザイナーになった!ホスピタリティでスクールを支える宮脇トレーナー
    2017.05.26
  • WebCampPro_インタビュー
    自分で稼ぐ力をつけるため、新卒5年目の営業マンがエンジニアに転職!【WebCampPro転職者インタビュー】
    2018.02.02
  • WebCamp_インタビュー
    “未経験”でもたった1ヶ月で営業からエンジニアとして転職!『WebCamp』受講者インタビュー
    2017.10.04
  • WebCamp_インタビュー
    【WebCamp卒業生インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!
    2018.01.15
  • WebCampPro_インタビュー
    未経験から上京し、エンジニアとしてチームラボグループに転職!【WebCampPro卒業生インタビュー】
    2018.03.10
  • WebCampPro_インタビュー
    未経験31歳からエンジニア転職を実現【実際に聞いてみた】
    2017.04.01
  • WebCamp_インタビュー
    【卒業生インタビュー】台湾で月間100万UUの訪日旅行メディアを手掛けるCEOが、プログラミングを学んで得たものとは?
    2018.01.15
  • WebCamp_インタビュー
    時間や場所にとらわれず自由に働くために必要なスキルとは?【WebCamp卒業生インタビュー】
    2018.01.26

◆当サイトで人気のプログラミング教室のおすすめランキングはこちら!
プログラミングは独学では非効率で、時間を無駄にするリスクがあります。効率的なカリキュラムで学べるスクールを受講しましょう。

Web Camp【マンツーマンサポート】1ヶ月短期集中でプログラミングを学ぶスクール
1ヶ月通い放題・メンター常駐の教室環境でWebサービス等作りたい方
TechAcademyオンラインで開講しているプログラミングスクール
オンラインでどこでも学べる!/教室に行くのが忙しい人でも安心!
Tech Camp教養としてのITスキルを学べるスクール
Webデザイン/AI(人工知能)/IOS/Androidアプリ制作/VRを学びたい方!
WebCampPro転職保証付き!エンジニアとして転職したい人におすすめ!
未経験からプロのエンジニアを3ヶ月で目指すプログラミングスクールです。
9月生募集中!当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のWebCamp Proコース。
8月受入枠は満員となっております。9月枠に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい
上記にあてはまる方は、ぜひご検討ください!

Rubyの配列やハッシュを扱っていく中で、並べ替えたいと思うことは、少なくないでしょう。

そんなとき、他のプログラム言語では、自分で並べ替えの処理を作らなければいけないことが多いです。しかし、Rubyであれば、標準でsortメソッドがあり、とても柔軟に使えるのです。

そんなRubyのsortメソッドについて、詳しく解説していきましょう。

Rubyのsortとは

Rubyのsortメソッドは、Enumerableモジュールに定義されている「並べ替えを行う」メソッドで、ArrayクラスやHashクラス、RangeクラスなどにMix-inされています。

※Arrayクラスについては、で詳しく解説しています
※Hashクラスについては、「【Ruby入門説明書】ハッシュについて解説」で詳しく解説しています
※Rangeクラスについては、「範囲オブジェクト」のひな形です。「【Ruby入門説明書】繰り返し、forについて解説」で、「範囲オブジェクト」を紹介しています
※モジュールやMix-inについては、「【Ruby入門説明書】リファレンス、moduleについて解説」を参照してください

sortの構文

sortメソッドの構文は、以下のどちらかになります。

単純な並べ替え

オブジェクト.sort

複雑な並べ替え

オブジェクト.sort do |ブロック引数a. ブロック引数b|
  並べ替えの評価
end

単純な並べ替えの場合、要素の昇順での並べ替えを行います。(数字の場合はそのまま昇順ですが、文字列の場合は文字コードの昇順になります)

また、複雑な並べ替えについては、並べ替えの評価結果によって並べ替えが行われます。

複雑な並べ替えのしくみ

sortメソッドへブロックを渡す複雑な並べ替えのポイントを詳しく説明しましょう。

まず、ブロック引数には、隣り合う2要素が渡されます。例えば、[9, 8, 7]という配列であれば、最初にブロック引数aには9、ブロック引数bには8が渡されるわけです。

この2要素をどう比較するかをプログラミングすることで、どんな複雑な条件でも並べ替えることができるでしょう。

並べ替えは、評価結果が負の値、0、正の値のうちのどれなのかによって判断され、負の場合はそのまま、正の場合は入れ替えられて、次の評価に遷移します。(0の場合は不定です)

なお、この評価結果は整数でなければエラーになりますので気をつけましょう。

極端な例ですが、負の数と正の数が混在している配列を、負の数と正の数で分けるような場合は、以下のようにsortを利用できます。

datas = [-1,1,-1,1,-1,1,1,-1,-1,1,1,-1]
sorted = datas.sort do |a|
  a
end
print(sorted)

(結果)

[-1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1]

評価結果が正になると入れ替えられるため、結果的に負の数が配列の先頭部(左)、正の数が後方部(右)へ移動しているわけです。

なお、ブロックなしのsortメソッドは、ブロックで「a <=> b」の並べ替えの評価をしているのと同じです。
※「<=>」は、「a < bであれば-1」、「a > bであれば1」、「a == bであれば0」を返すメソッドです。

datas = [9, 8, 7, 6, 5, 4, 3, 2, 1]

sorted = datas.sort
block_sorted = datas.sort do |a, b|
  a <=> b
end

p(sorted)
p(block_sorted)

(結果)

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

降順にしたい

sortメソッドは、ブロックを利用しなければ,昇順に並べ替えます。

そのため、降順に並べ替えるには必ずブロックを使わなければいけないかというと、じつはそうではありません。

Arrayクラスにあるreverseメソッドを使うことで、簡単に降順にすることができるのです。

もちろん、ブロックを使って降順にすることもできますので、合わせて紹介しておきます。

datas = [5, 8, 1, 4, 9, 3, 6, 2, 7]

sorted = datas.sort.reverse         # reverseメソッドを使う
block_sorted = datas.sort do |a, b| # ブロックで比較順序を逆にする
  b <=> a
end

p(sorted)
p(block_sorted)

(結果)

[9, 8, 7, 6, 5, 4, 3, 2, 1]
[9, 8, 7, 6, 5, 4, 3, 2, 1]

“未経験”でもたった1ヶ月で営業からエンジニアとして転職!『WebCamp』受講者インタビュー
2017-10-04 10:26
今回の記事では、未経験からWebCampを1ヶ月受講し、その後エンジニアとして転職をした喜田さんにお話を伺いました。 <プロフィール> 喜田 大介 さん (28歳) 大学時代はプ...

sortよりもsort_by?

sortメソッドによく似た、sort_byメソッドも紹介しておきます。

sort_byもEnumerableモジュールで定義されており、sortメソッドと同じクラスにMix-inされています。

用途もほぼ同じですが、sort_byの場合は、必ずブロックを渡す必要がありますので、以下の構文だけになります。

オブジェクト.sort_by do |ブロック引数|
  処理
end

sort_byの構文はブロックありのsortメソッドによく似ていますが、動きはブロックなしsortメソッドに似ているのが、とても興味深いところです。

その動きを説明すると、以下のようになります。

  1. ブロック引数に要素が渡される
  2. 処理を行う
  3. すべての処理結果が集まったところで、処理結果をもとに昇順に並べ替える

つまり、ブロックありのsortメソッドのように、その都度入れ替えを行うのではなく、ブロックの処理結果をもとに昇順に並べ替えるのです。

そのため、単純な数値の配列などではメリットを感じられないと思います。

しかし、各要素に複雑な処理を行う必要がある場合などは、sortメソッドの場合、2つの要素に処理を行って比較するため、プログラムコードの可読性が落ちてしまいます。

その点、sort_byメソッドでは、単純に「要素に処理している」だけですので、シンプルなプログラムコードになって、理解しやすいのです。

また、sortメソッドは、隣り合う要素2つに対して、毎回処理を行って比較しますので、処理の回数が膨大になります。しかし、sort_byメソッドでは、1度すべての要素に処理を行ったあと、その結果を使って比較するので、処理の回数は要素数と同じになるだけです。

そのため、処理に時間がかかる場合などは、処理速度に大きな差ができることでしょう。

もし、並べ替えを行うに当たって、各要素に複雑な処理を行う必要があるのであれば、sort_byメソッドを使う方向で検討することをおすすめします。

コツコツ独学×スクールで実践。未経験からエンジニアに転職!【WebCamp卒業生インタビュー】
2018-03-22 23:28
今回の記事では、独学でPHPを1年半学習し、その後WebCampを受講して未経験からエンジニアへと転職された佐々木さんにお話を伺いました。 <プロフィール> 佐々木 祐樹 さん(2...

Hashのsort

ここまでの説明は、sortメソッド(sort_byメソッド)の共通点と言えます。

また、ArrayクラスやRangeクラスなど、要素が1つの場合は、ここまで説明した使用方法で、ほとんどの場合は困ることがありません。

しかし、Hashクラスについては、少し工夫が必要ですので、もう少し詳しく説明していきましょう。

Hashクラスでsortメソッドを使うときにポイントとなるのは、「Hashの要素には、キーと値の2つのデータが格納されている」ということです。

ArrayクラスやRangeクラスの場合は、要素に1つのデータしかありませんので、要素同士の比較は意図通りに行えるでしょう。しかし、1つの要素に2つのデータがある場合、比較先を正しくしなければ、思ったような並べ替えになりません。

そのため、Hashクラスのsortメソッドを使うときには、キーと値のどの要素を比較に使っているのかをしっかりと意識してプログラムしなければいけないのです。

なお、「どの要素を比較に使っているのか」を意識するというのは、「ブロック引数に渡されるのは、どの要素なのか」、ということを意識することです。その視点で、説明していきましょう。

ブロックなしsort

前述のように、Arrayオブジェクトからブロックなしのsortを利用すると、昇順に並べ替えられます。では、Hashオブジェクトの場合は、どうなるでしょうか?

実際に確かめてみましょう。念のため、ブロックなしと同等のブロックありでも確認してみます。

sort00-1.rb

datas = {"c"=>10, "b"=>1, "a"=>100}

sorted = datas.sort
block_sorted = datas.sort do |a, b|
  a <=> b
end

p(sorted)
p(block_sorted)

(結果)

[["a", 100], ["b", 1], ["c", 10]]
[["a", 100], ["b", 1], ["c", 10]]

ブロックなしsortの場合は、キーの昇順に並べ替えられています。

つまり、sortメソッドは、何もしなければ各要素の先頭の値をブロック引数に持ってきて処理を進めるということになります。

もちろん、reverseメソッドを使えば、キーの降順にすることもできます。

ハッシュが返ってきていない?

ここで少しだけ、注意点がありますので、補足します。

Hashクラスのsortメソッドの動きを見てきましたが、じつはHashクラスのsortメソッドには、もう1点重要なポイントがあります。

それは、ハッシュではなく配列の配列になっている点です。

これまで紹介してきたプログラムの結果の通り、結果は[[],[],[]]の形で出力されています。つまり、Hashオブジェクトを並べ替えたにもかかわらず配列になっているわけです。

もちろん、この点を理解してプログラムを作っていれば、特に問題ありませんし、配列が返ってくるほうが都合が良い場合もあります。しかし、ハッシュにしたい場合もあるでしょう。

そんなときに便利なのが、「to_h」メソッドです。

このメソッドを使えば、配列の配列がハッシュに変換されます。

sort00-1.rbを修正して確認してみましょう。

sort00-2.rb

datas = {"c"=>10, "b"=>1, "a"=>100}

sorted = datas.sort
block_sorted = datas.sort do |a, b|
  a <=> b
end

p(sorted.to_h)   # こちらだけハッシュに変換
p(block_sorted)

(結果)

{"a"=>100, "b"=>1, "c"=>10}
[["a", 100], ["b", 1], ["c", 10]]

ぜひ、活用してください。

値でソート

前述のように、何もしなければsortメソッドはキーの値で並べ替えを行います。しかし、当然ながら値で並べ替えたい場合もあるでしょう。

そんな場合は、ブロックを利用して並べ替えの条件を変更する必要があります。

しかし、どう変更すべきなのか、ヒントがなければ分かりません。そこでポイントなのが、ブロック引数に渡されているデータです。

sort00-1.rbを改造して、ブロック引数に渡されているものが何なのか、見てみましょう。
※ブロックなしsortは削除しています。

sort00-3.rb

datas = {"c"=>10, "b"=>1, "a"=>100}

block_sorted = datas.sort do |a, b|
  print("#{a} <=> #{b}\n")        # aとbに渡されているものを表示する
  a <=> b
end

p(block_sorted)

(結果)

["b", 1] <=> ["c", 10]
["a", 100] <=> ["c", 10]
["b", 1] <=> ["a", 100]
[["a", 100], ["b", 1], ["c", 10]]

結果の通り、ブロック引数aとbには、それぞれの要素を配列にしたものが渡されています。そして、メソッドでは、渡された配列の1つめの要素だけを見て、評価しているわけです。

つまり、ブロック内の「a b」というのは、Hashオブジェクトのsortの場合、「a[0] b[0]」だということになります。

ここまでくれば、値で並べ替えする方法が見えてきたのではないでしょうか?

この「評価対象」を1つめの要素ではなく、2つめの要素=ハッシュの値を見て評価するように修正すれば、値で並べ替えができるというわけです。

修正したものが、以下です。
※ブロック内のprintは削除しています

sort00-4.rb

datas = {"c"=>10, "b"=>1, "a"=>100}

block_sorted = datas.sort do |a, b|
  a[1] <=> b[1]
end

p(block_sorted)

(結果)

[["b", 1], ["c", 10], ["a", 100]]

以上で、値での並べ替えができます。

また、上述のブロック引数に渡されているデータがどんなものかが分かれば、キーや値での並べ替え以外にも、キーと値を組み合わせた任意の並べ替えが可能になるでしょう。

時間や場所にとらわれず自由に働くために必要なスキルとは?【WebCamp卒業生インタビュー】
2018-01-26 13:03
今回の記事では、WebCampに1ヶ月間通い、未経験からエンジニアとして転職した星野さんにお話を伺いました。 <プロフィール> 星野 智洋 さん(25) 学生時代は日本大学芸術学部...

破壊的メソッドsort!

sortメソッドは、自分自身を変更することなく、並べ替えられた配列を戻り値として返します。

しかし、ArrayクラスやRangeクラスのsortメソッドには、自分自身を並べ替えてしまう破壊的メソッドsort!も準備されています。

sort!メソッドを使うと、もとの並び順が失われてしまいますが、戻り値を保持しておく変数が不要になるなど、プログラムによっては、sort!メソッドを使ったほうがシンプルになる場合もあります。

プログラムの流れを考慮しつつ、最適なものを使うようにしましょう。
※Hashクラスの場合は、sort!は使えませんので、注意しましょう。

問題「売り上げ順位」

次のような、金額と売れた個数が記録されたハッシュがあります。売上金額の多いものから降順に並べてください。なお、並べ替えた結果は、ハッシュであること。

pv = {100=>10, 500=>1, 300=>4, 200=>3, 600=>1, 150=>4}

まとめ

今回は、sortメソッドについて、説明しました。

sortメソッドは、単純に使うだけでは、それほど利便性があるように感じないかもしれませんが、そのしくみを知ってブロックを組み合わせれば、とても柔軟なメソッドです。

配列やハッシュは、Rubyプログラムを作る上で、数多く扱うことになります。

sortメソッドを使って、より複雑な処理にも挑戦していきましょう。

・sortメソッドは、Enumerableモジュールに定義されており、ArrayクラスやHashクラスにMix-inされている
・ブロックなしのsortメソッドは、要素を昇順に並べ替える
・ブロックありのsortメソッドは、ブロックの評価結果によって、並べ替える
・評価結果が負の値のときはそのまま、正の値のときは入れ替える
・sort_byを使うことで、ブロックをシンプルにでき、かつ処理速度が速まる
・Hashのsortメソッドを使うときには、キーと値のどの要素を使っているのかを意識すること
・Hashのブロックなしsortは、キーで並べ替える
・Hashのブロックありsortのブロック引数には、Hashの要素が[キー, 値]の配列が渡されている
・sortメソッドは、並べ替えられた配列を返す。sort!は自分自身を並べ替えて返す
・Hashのsortメソッドには、sort!はない

問題の答え

pv = {100=>10, 500=>1, 300=>4, 200=>3, 600=>1, 150=>4}

sorted = pv.sort_by do |val|
  val[0] * val[1]
end
sorted = sorted.reverse.to_h

p(sorted)

WebCamp・WebCamp Proについて

WebCampは1ヶ月でプログラミング・Webデザインスキルを学ぶ通い放題のプログラミングスクールです。WebCamp Proは3ヶ月間で未経験から即戦力エンジニアを育成するプログラミングスクールです。

2つのサービスを運営するインフラトップでは、「学びと仕事を通して人生を最高の物語にする」という理念で会社を経営しています。

キャリアアップを目指す方は、この機会に私達と一緒にプログラミングを学んでみませんか?

8月枠も残りわずか当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のWebCamp Proコース。
7月受入枠は満員となっております。8月枠に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい
上記にあてはまる方は、ぜひご検討ください!

▼未経験から1ヶ月でWebデザイン・プログラミングを学びたい方はこちら!

▼ついに開講!オンラインでWebデザインを学びたい方はこちら!

 

【インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!

ブラジルから帰国し技術をつけようとRubyエンジニアを目指してWebCampでRubyを学び、見事Webエンジニアとして転職を果たした田中さんにお話を伺いました。

Rubyの学習がしたい。基礎をしっかりと理解したい

転職のサポートがほしい

と考えている方はぜひお読み下さい。

【WebCamp卒業生インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!
2018-01-15 13:23
今回の記事では、WebCampで1ヶ月間Rubyを学習し、Webエンジニアとして転職した卒業生の田中さんにお話を伺いました。 <プロフィール> 田中 デニス 昭彦さん(...
関連キーワード
Rubyの関連記事
  • 【Ruby入門説明書】ruby sliceについて解説
  • 【Ruby入門説明書】chompについて解説
  • 【Ruby入門説明書】selectについて解説
  • 【Ruby入門説明書】matchについて解説
  • 【Ruby入門説明書】リファレンス、sortについて解説
  • 【Ruby入門説明書】リファレンス、moduleについて解説

当サイトで人気のオススメ転職サービスTOP3

1位 マイナビエージェント×IT

おすすめポイント

・平日忙しい人も、土曜日開催の個別キャリア相談会に参加できる

・職種や仕事内容(要件定義、上流工程から携わる仕事など)の要望が細かくできる
・マイナビの規模を活かした豊富で幅広い求人数

マイナビエージェント×ITの登録はこちら

2位 レバテックキャリア

おすすめポイント

・求人登録数4,000件以上

・エンジニア未経験、経験者両方に対応

・有名企業の採用担当者インタビューがみれる

・一次面接NGからの内定実績もあるほど、内定率が高い

レバテックキャリアの登録はこちら

 3位 type転職エージェント

おすすめポイント

転職者の71%が年収アップ

・IT系企業、特にエンジニアに限らず営業職の求人も充実している

各職種専門の転職アドバイザーが援助

type転職エージェントの登録はこちら

おすすめの記事