げんきちの秘密基地

エンジニアリングが世の中の思いを実現してきた歴史に気づき、29歳未経験からWEBエンジニアとして転生!【Danger】綺麗事を割と本気で言ってきます【GitHub】https://github.com/0840kg【Twitter】https://twitter.com/0840kg

誰でもわかる!sortメソッドのブロックの中身について

ぞす!げんきちです!\\\\٩( 'ω' )و ////

 

「いや、誰だよ」って方は、下記リンクを見てやってください。

  1. はじめまして!げんきちです! - げんきちの秘密基地

  2. 僕がエンジニアになりたい理由 - げんきちの秘密基地

目次〜

f:id:www08056561815:20190225130157p:plain

きっかけ

expect(assigns(:tweets)).to match(tweets.sort{ |a, b| b.created_at <=> a.created_at } )

 

初めて見た時に思いました。

なにこの、わかりそうでわからない感じ...

特に、sortの後ろの方とか。

ということで、調べて見ました\(^o^)/

 

sortとは

配列やハッシュの中身を並び替えることができるrubyのメソッド。

 

例)昇順

ary2 = ["9", "7", "10", "11", "8","712","1"]
p ary2.sort                             #=> ["1", "10", "11", "7", "712","8", "9"] (文字列としてソートするとこうなる)
p ary2.sort{|a, b| a.to_i <=> b.to_i }  #=> ["1", "7", "8", "9", "10", "11","712"] (ブロックを使って数字としてソート)

 

文字列のままだと、文頭の数字の大小が優先されるみたいです。

あと、ブロックで処理した方が拡張性が高いようです。

#今回の場合は、文字列を数字として認識してくれました。

 

例)降順

デフォルトだと昇順です。

降順にする場合も調べてみました。

ary2 = ["9", "7", "10", "11", "8","712","1"]
p ary2.sort.reverse                             #=> ["9", "8", "712", "7", "11", "10","1"] (文字列としてソートするとこうなる)
p ary2.sort{|a, b| b.to_i <=> a.to_i } #=> ["712", "11", "10", "9", "8", "7", "1"](ブロックを使って数字としてソート)

①  .reverseメソッドを使う。

②  ブロックの最後の式(ブロックの戻り値)のブロック変数(a,b)を逆にする。

 

docs.ruby-lang.org

 

わかりにく原因

①については、そういうメソッドだと思います。

問題は、②。

ここが分かりそうでわからない原因でした。

ということで、分解してみました\(^o^)/

 

ブロック変数の中身は?

比較する対象の要素 2つ(a,b)

例)"9"と"7"

 

<=>とは

その名を「宇宙船演算子

まず、カックイイッ...!!!

 

例)

10 <=> 20   #  -1
20 <=> 10   #   1
20 <=> 20   #   0
20 <=> '20' # nil

左辺のオブジェクトがレシーバーになる。

レシーバー側が大きければ1。

レシーバー側が小さければ-1。

レシーバー側と等しければ 0。

レシーバー側と比較できなければnil

 

<=>の結果とは

   -1    0    1
----|----|----|----
    <    =    >

与えられた左辺と右辺について成立する <、=、> いずれかの演算子に対応する数値。

 

qiita.com

 

sort {〜}内でされていること

①配列の各要素に対して、他の要素と比較した際の戻り値の合計を割り当てる。

②その値を昇順で並べる。

 

ブロックの最後の式(ブロックの戻り値)のブロック変数(a,b)を逆にすると、sortの結果が昇順から降順になる理由

各要素に割り当てられる「戻り値の合計」が変わるから。

 

例)昇順

ary2 = ["9", "7", "10", "11", "8","712","1"]

p ary2.sort{|a, b| a.to_i <=> b.to_i }  #=> ["1", "7", "8", "9", "10", "11","712"] 

 

  |a= 10, b=9|の時の戻り値 => 1

+ |a= 10, b=7|の時の戻り値 => 1

+ |a= 10, b=11|の時の戻り値 => -1

+ |a= 10, b=8|の時の戻り値 => 1

+ |a= 10, b=712|の時の戻り値 => -1

+ |a= 10, b=1|の時の戻り値 => 1

ーーーーーーーーーーーーーーーーー

(10に対する戻り値の合計) = 2

 

例)降順

ary2 = ["9", "7", "10", "11", "8","712","1"]
p ary2.sort{|a, b| b.to_i <=> a.to_i }  #=> ["712", "11", "10", "9", "8", "7", "1"]

 

  |a= 10, b=9|の時の戻り値 => -1

+ |a= 10, b=7|の時の戻り値 => -1

+ |a= 10, b=11|の時の戻り値 => 1

+ |a= 10, b=8|の時の戻り値 => -1

+ |a= 10, b=712|の時の戻り値 => 1

+ |a= 10, b=1|の時の戻り値 => -1

ーーーーーーーーーーーーーーーーー

(10に対する戻り値の合計) = -2

 

とりあえず、スッキリしました。

数字が絡んでくると、面白いです!

 

<一日一新>

渋谷 大和田の豚骨ラーメン。

チャーシューがホロっホロ。

 

<学習進捗>

学習開始からの期間 :78日
今日までの合計時間:778h
今日までに到達すべき目標時間:712h
目標との解離:66h
10,000時間」まで、

 

残り・・・9,222時間!」

 

以上です。

読んでくれた方々、ありがとうございました!((_ _ (´ω` )ペコ。

 

genkichi.hateblo.jp

genkichi.hateblo.jp

 

f:id:www08056561815:20190224095507g:plain

twitter.com