JavaScriptで配列の要素(数値)を昇順・降順に並び替えるために、漠然とsortに比較関数を渡して書いていたので、sortに比較関数を渡したときの挙動を理解するために詳細を調べました。
#ソートプログラム
let array = [1, 5, 4, 2, 3];
console.log(array.sort((a, b) => a - b)); //[1, 2, 3, 4, 5]
console.log(array.sort((a, b) => b - a)); //[5, 4, 3, 2, 1]
シンプルなソートプログラムは上記のようなものになるかと思います。
比較関数内の返り値を、昇順のときは第一引数から第二引数、降順のときは第二引数から第一引数を減算した結果にしています。
このようなsortのコールバック関数の返り値の違いがどのようにソート順に違いを生むのでしょうか。
#sortのコールバック関数の返り値ごとの挙動
sortはコールバック関数として、下記のような引数を二つ取り、値を返す比較関数を定義できます。
compareFunction(a, b) {
//処理内容
}
MDNによると、sortにコールバック関数が与えられたとき、undefined以外の全ての配列要素はその返り値に基づきソートされます。(undefinedは配列の末尾に並べられます。)
返り値別のソート結果は下記です。
- 0未満のとき
- aはbより小さいインデックスにソートされる
- 0のとき
- aとbは互いにインデックスを変更しない
- 0より大きいとき
- aはbより大きいインデックスにソートされる
ここで冒頭のプログラムを参照すると、昇順にソートするときは返り値がa-bとなっており、仮にa=5, b=1だった場合はa-b(=4)は0より大きいことから、a(=5)はb(=1)よりも大きいインデックスにソートされ、結果として昇順となります。
逆に降順にソートするときは返り値がb-aとなっており、昇順のときと同様にa=5, b=1の場合を考えるとb-a(=-4)は0未満のため、a(=5)はb(=1)よりも小さいインデックスにソートされ、結果として降順となります。
このようにして、冒頭のソートプログラムは昇順・降順の違いを生んでいるのですね。