##sortメソッド
sortとは、日本語で「並び替える」という意味です。つまり、sortメソッドとは、ある一定の基準で並び替えるメソッドです。
実際に具体例を見てみましょう
ary = [4, 2, 9, 8, 3, 16, 10]
p ary.sort
=> [2, 3, 4, 8, 9, 10, 16]
sortメソッドは、デフォルトで昇順に並び替えるメソッドです。上記の例では、配列の中身が昇順で並び変わっています。
降順で並び替えるには、2つの方法があります。
➀reverseメソッドを使う
➁<=>演算子を使う
順に説明していきましょう
##➀reverseメソッド
reverseとは「反転する」という意味です。つまり、reverseメソッドは、配列やハッシュなどの値を反転させるメソッドなんです。
実際にコードを書いてみると以下のようになります。
ary = [4, 2, 9, 8, 3, 16, 10]
p ary.sort.reverse
=> [16, 10, 9, 8, 4, 3, 2]
このように書けます。個人的にはメソッドを2個連続書けることに驚きました(今更なんですけどね笑)。同じクラスのメソッドは連続で書けるみたいですね。
##➁<=>演算子
宇宙船演算子ともいわれています。見た目が宇宙船に似ているからだそう。個人的にはあまり似ていないように見えますが笑
どんな使い方をするかというと、公式ドキュメントに書かれているのは
self <=> other は
・self が other より大きいなら正の整数
・self と other が等しいなら 0
・self が other より小さいなら負の整数
・self と other が比較できない場合は nil
実際に具体例を見てみましょう
2 <=> 1
=> 1
2 <=> 2
=> 0
2 <=> 3
=> -1
2 <=> 'hoge'
=> nil
上記の具体例をみると、公式ドキュメントに書いてあることが理解できるとおもいます。要は、
左辺が右辺よりも大きければ、1を返し、
左辺と右辺が同じでなら、 0 を返し、
左辺が右辺よりも小さければ、-1を返し、
比較できない場合は、nilを返す
それを理解したうえで、以下のようなコードを書くと降順になるんです。
ary = [4, 2, 9, 8, 3, 16, 10]
p ary.sort {|a, b| b <=> a}
=> [16, 10, 9, 8, 4, 3, 2]
僕はこの書き方を見て、{|a, b| b <=> a}をみて、「どんな処理をしてるんだろう?」って思ったので、どんな処理をしているのかを解説していきます。
##{|a, b| b <=> a}は何をしているのか?
これを考えるとき、比較するとよいのが下記のコードです。
ary = [4, 2, 9, 8, 3, 16, 10]
p ary.sort{|a, b| a <=> b}
=> [2, 3, 4, 8, 9, 10, 16]
ここで考えなければならないのが、各要素の「戻り値の合計」の変化によるものなんです。どんなものかを見ていきましょう
|a= 4, b=2|の時の戻り値
4 <=> 2
=> 1
|a= 4, b=9|の時の戻り値
4 <=> 9
=> -1
|a= 4, b=8|の時の戻り値
4 <=> 8
=> -1
|a= 4, b=3|の時の戻り値
4 <=> 3
=> 1
|a= 4, b=16|の時の戻り値
4 <=> 16
=> -1
|a= 4, b=10|の時の戻り値
4 <=> 10
=> -1
戻り値の合計は、1-1-1+1-1-1=-2
|a = 2, b=4|の時の戻り値
2 <=> 4
=> -1
|a = 2, b=9|の時の戻り値
2 <=> 9
=> -1
|a = 2, b=8|の時の戻り値
2 <=> 8
=> -1
|a = 2, b=3|の時の戻り値
2 <=> 3
=> -1
|a = 2, b=16|の時の戻り値
2 <=> 16
=> -1
|a = 2, b=10|の時の戻り値
2 <=> 10
=> -1
戻り値の合計は、-6
このように、a = 16までをやってみると、戻り値の合計が7個出てきます。
a=4のとき、戻り値の合計は、-1
a=2のとき、戻り値の合計は、-6
a=9のとき、戻り値の合計は、2
a=8のとき、戻り値の合計は、0
a=3のとき、戻り値の合計は、-4
a=16のとき、戻り値の合計は、6
a=10のとき、戻り値の合計は、5
この戻り値の合計を比較して、少ない順にみていくと、[2, 3, 4, 8, 9, 10, 16]と昇順になるんです。
つまり、
ary = [4, 2, 9, 8, 3, 16, 10]
p ary.sort{|a, b| a <=> b}
=> [2, 3, 4, 8, 9, 10, 16]
のようなブロックにすると昇順になるんです。理由が分かりましたね。
では逆に、
ary = [4, 2, 9, 8, 3, 16, 10]
p ary.sort{|a, b| b <=> a}
この場合はどうなるのでしょうか。
同じように計算すると、
a=4のとき、戻り値の合計は、1
a=2のとき、戻り値の合計は、6
a=9のとき、戻り値の合計は、-2
a=8のとき、戻り値の合計は、0
a=3のとき、戻り値の合計は、4
a=16のとき、戻り値の合計は、-6
a=10のとき、戻り値の合計は、-5
この戻り値の合計を比較して、少ない順にみていくと、[16, 10, 9, 8, 4, 3, 2]と降順になるんです。
まとめると、{|a, b| b <=> a}は何をしているのかというと、要素同士の比較をしているということです。
提示されているプログラムは、ブロック内で降順になります。降順になる理由は、先ほど述べましたね。
そして、降順になった配列にreverseメソッドを適用することで昇順になるんです。
よって、今回の正解は、選択肢➁です
以上です。
何か間違いがございましたら、ご教示いただけますと幸いです。
【参考文献】