この投稿は
JavaScriptのsort()メソッドの使い方が分からなかったので備忘録としてのメモです。
sort()メソッドを使ったコードを見ると、みんな当たり前のように引数に関数を使っているし、戻り値の訳が分からんし・・・ってことで。
基本形
JavaScriptのsort()メソッドは、どうやら「高階関数」ってやつで、引数に関数を指定するっぽい。
MDN によると、引数として設定する関数は以下のようにaとbを引数とした、無名のアロー関数で記述するんだそうだ。(もちろん、別の書き方もあるはず。)
const array = []; //配列の宣言
array.sort((a,b) => {
//関数の中身
});
こんな感じかな?
引数aとbは、配列から適当に「要素」を代入してくれるらしい。開発者はaとbを比較とか演算すればいいんだそうだ。
戻り値の意味
関数の戻り値が一番意味が分からなかったんだよね。サンプルのプログラムを見るとみんなこんな風に書いてある。
array.sort((a,b) => {
return a-b;
});
なんで計算結果を返すといいんだか? 全く分からなかった。
これも、MDN に書いてあった。
戻り値で要素aとbの並びを変えるらしい。
戻り値 | 挙動 | 要素aとbの位置関係 | |||
---|---|---|---|---|---|
0以上 | a を b の後ろに並べる |
|
|||
0以下 | b を a の後ろに並べる |
|
|||
0 | 何もしない | 元と同じ |
なので、戻り値が0以上の時は、並びが逆転するっぽい。
これで、数値を戻り値にする意味がわかった。
上記を踏まえて昇順ソート
上記を踏まえて、1次元配列の昇順ソートをするとなると、
const array = [4,4,2,3,2,3]; //テスト用に配列に要素を設定
array.sort((a,b) => {
if (a == b) {
return 0;
} else if (a > b) {
return 1;
} else {
return -1;
}
});
のようになる。
ここで、戻すべき戻り値をもう一度見てみよう。
「0以上」「0以下」「0」となっている。
「1」「ー1」「0」ではない。
なので、昇順ソートは以下のようにも書き換えられるみたい。
const array = [4,4,2,3,2,3]; //テスト用に配列に要素を設定
array.sort((a,b) => {
return a - b;
});
数値であればこっちの方がすっきりする。
降順ソートは?
1次元配列の降順ソートをするとなると、b より a が小さい場合0以上を戻せばいいのだから、
const array = [1,4,2,3,2,3]; //テスト用に配列に要素を設定
array.sort((a,b) => {
if (a == b) {
return 0;
} else if (a > b) {
return -1;
} else {
return 1;
}
});
のようになる。また、以下のようにも書き換えられる。
const array = [1,4,2,3,2,3]; //テスト用に配列に要素を設定
array.sort((a,b) => {
return b - a;
});
二次元配列のソート
キー1つで昇順の場合
二次元配列を1つのキーでソートする時はこう考えるとよさそう。
二次元配列を表と考えて、引数に渡される要素は「行」部分と考える、また、行の中の「列」を比較するようにする。
こんな感じ。
const array = [
[4,2],
[4,1],
[2,2],
[3,3],
[2,2],
[3,5]
]; //テスト用に配列に要素を設定
//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
//表でいう列部分を比較する。
if (a[0] == b[0]) {
return 0;
} else if (a[0] > b[0]) {
return 1;
} else {
return -1;
}
});
また、以下のようにも書き換えられる。
const array = [
[4,2],
[4,1],
[2,2],
[3,3],
[2,2],
[3,5]
]; //テスト用に配列に要素を設定
//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
//表でいう列部分を演算する。
return a[0] - b[0];
});
キー2つで昇順の場合
二次元配列を2つのキーでソートする時は、
キー1が同じときだけ、キー2を比較すると良さそうだ。
const array = [
[4,2],
[4,1],
[2,2],
[3,3],
[2,2],
[3,5]
]; //テスト用に配列に要素を設定
//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
//表でいう列部分(キー1)を比較する。
if (a[0] == b[0]) {
//キー1が同じときだけ、キー2を比較する。
//表でいう列部分(キー2)を比較する。
if (a[1] == b[1]) {
//キー1とキー2が同じなら0を戻す。
return 0;
} else if (a[1] > b[1]) {
return 1;
} else {
return -1;
}
} else if (a[0] > b[0]) {
return 1;
} else {
return -1;
}
});
また、以下のようにも書き換えられる。
const array = [
[4,2],
[4,1],
[2,2],
[3,3],
[2,2],
[3,5]
]; //テスト用に配列に要素を設定
//aとbには、表でいう行部分([4,1]とか[2,2]とか・・・)が引き渡される。
array.sort((a,b) => {
//表でいう列部分(キー1)を比較する。
if (a[0] == b[0]) {
//キー1が同じときだけ、表でいう列部分(キー2)を演算する。
return a[1] - b[1];
} else {
//表でいう列部分(キー1)を演算する。
return a[0] - b[0];
}
});
オブジェクトのソート
オブジェクト配列の場合は、a や b に引き渡されるものはオブジェクト( {'v1':4,'v2':4} など)。
比較はオブジェクトの値を比較すれば良さそう。
let array = [
{'v1':3,'v2':3},
{'v1':4,'v2':4},
{'v1':1,'v2':3},
{'v1':2,'v2':4},
{'v1':1,'v2':1},
{'v1':2,'v2':4},
]
//aやbにはオブジェクト({'v1':2,'v2':4})が引き渡される。
array.sort((a,b) => {
//オブジェクトの値を比較。
if (a.v1 == b.v1) {
return 0;
} else if (a.v1 > b.v1) {
return 1;
} else {
return -1;
}
});
これも、次のように書き換えられる。
let array = [
{'v1':3,'v2':3},
{'v1':4,'v2':4},
{'v1':1,'v2':3},
{'v1':2,'v2':4},
{'v1':1,'v2':1},
{'v1':2,'v2':4},
]
//aやbにはオブジェクト({'v1':2,'v2':4})が引き渡される。
array.sort((a,b) => {
//オブジェクトの値を比較。
return a.v1 - b.v1;
});
まとめ
僕なりのまとめ。
- sort()メソッドを使うためには、引数に以下のように a と b を引数とした関数を記載。
- その関数内で、0以上、0以下、0のいずれかを戻す。
- 戻り値が、0以上なら、要素の並びが逆転する。
const array = []; //配列の宣言
array.sort((a,b) => {
//関数の中身
});