業務では、配列のソートはlodashを使うのですが、細かく条件を入れてソートしたい時はsortメソッドの方が便利です。そこで、今一度このsortの仕組みを整理してみました。
sortメソッドとは
配列に対して、順番に2個ずつ要素を取り出して計算/比較した結果を正もしくは負の数で返す事で並び替えをしてくれる。
[ARRAY_DATA].sort((a, b) => ここでa, bを計算,比較して,正か負の数を返す)
並び替えの仕組み:
結果が正 → 第一引数 a を 第二引数 b の後に並べる → [b, a]
結果が負 → 第一引数 a を 第二引数 b の前に並べる → [a, b]
実際に見ていきましょう、本記事内のコードは以下のサンプルデータを使っています。
// サンプルデータ
// *startDateは本来UNIXタイムスタンプですが、便宜上わかりやすくしてます。
const arr = [
{ eventName: "イベントB", startDate: 3, round: null },
{ eventName: "イベントA", startDate: 5, round: null },
{ eventName: "イベントC", startDate: 3, round: 1 },
{ eventName: "イベントD", startDate: 4, round: 2 },
{ eventName: "イベントE", startDate: 1, round: null },
]
sortの書き方(1) 第一引数と第二引数の差で判定
昇順(データを小さい順に並べる)の場合
arr.sort((a, b) => a.startDate - b.startDate)
aがbより小さい場合、負の数になるので、並び替えの仕組みの以下が適用される
結果が負 → 第一引数a を 第二引数b の前に並べる → [a, b]
降順(データを大きい順に並べる)の場合
arr.sort((a, b) => b.startDate - a.startDate)
bがaより大きい場合、正の数になるので、並び替えの仕組みの以下が適用される
結果が正 → 第一引数 を 第二引数 の後に並べる → [b, a]
sortの書き方(2) 第一引数と第二引数を比較して、正、負の数を返す
昇順(データを小さい順に並べる)の場合
arr.sort((a, b) => a.startDate < b.startDate ? -1 : 1)
aがbより小さい場合、-1を返すので、並び替えの仕組みの以下が適用される
結果が負 → 第一引数a を 第二引数b の前に並べる → [a, b]
降順(データを大きい順に並べる)の場合
arr.sort((a, b) => a.startDate < b.startDate ? 1 : -1)
bがaより大きい場合、正の数になるので、並び替えの仕組みの以下が適用される
結果が正 → 第一引数 を 第二引数 の後に並べる → [b, a]
*この様に比較演算子を変えても同じ条件になります
arr.sort((a, b) => a.startDate > b.startDate ? -1 : 1)
なぜ 1 と -1 なのか?
正数か負の数かを返せばいいので、必ずしも1, -1
である必要はなく、23, -25
などどんな数字でも結果は同じですが慣例的に 1, -1が使われています。
細かいソートルールを適用させる
サンプルデータの配列は各ObjectにstartDateという開始日の情報を持ってるので、それを昇順、降順で並び替えるのは前述の通りです。
ただ、startDateが同じデータが存在する事もあり得るので、その場合はroundを見て、roundがある方を上にしたいという要件があったとします。そういう細かいソートルールを適用させる時の実装をしてみます。
今回のサンプルデータだと、イベントBとCが同じstartDateで、Cがround値を持っているので、Cを上にしたい。という事になります。
arr.sort((a, b) => {
// 同じstartDateだった場合
if (a.startDate === b.startDate) {
// aにround値があれば上にしたいので、負の数を返す
return a.round ? -1 : 1
}
// 降順にするので、b - a を実行
return b.startDate - a.startDate
// これでも同じです
// return a.startDate < b.startDate ? 1 : -1
})
上記の結果はこの様になり、イベントCが上に来てるのがわかると思います。
参考:MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort