配列に対してsortメソッドを使うと、配列内の要素を並び替えることができます。
例えば、以下のように配列内に英単語がある場合には、ABC順にソートされます。
let data = ["November","February","August"]; data.sort(); console.log(data); // ["August", "February", "November"]
ただし、上の例の英単語は”月”を表すので、Februaryを先頭に月順に並べるほうが都合がよい場合があります。
sortメソッドの引数には、並び替えの規則を定義したコールバック関数を指定できます。
では、自分の好きな順序に並び替えるには、どのように関数を定義すれば良いでしょうか?
並び替えの規則を定義する
まず、sortメソッドの引数に指定する「並び替えの規則を定義を行う関数」について挙動を見ていきたいと思います。
例として、配列のデータを昇順(値が小さい順)に並べ替えてみます。
function compare(a, b) { if (条件1:aがbよりも小さい) { return 負の値; } if (条件2:aがbよりも大きい) { return 正の値; } return 0; // aとbが等しい }
上記の「データを昇順に置き換える」関数は、引数に2つの変数a,bを指定して、結果として正の値、負の値、 0を返します。
aとbはソートを行う配列内のある要素について、前後関係のある値だと思ってください。
この時、returnの値によって、aとbで指定した値は以下のようにソートされます。
- “負の値”のときは、aはbの前に置かれる
- “0”のときは、aとbの位置は変わらない
- “正の値”のときは、bはaの前に置かれる
なので、昇順に並び替えるためには、
- “負の値”のときは、aがbよりも小さいとき
- “0”のときは、aとbの値が同じ大きさの時
- “正の値”のときは、aがbよりも大きいとき
のようになります。
実際には、以下のようにaとbの差分を返してあげるだけで、昇順を行う関数(desiredComparison)が実現できます。
let data = [3,-0.5,0,2,-10]; data.sort(desiredComparison); console.log(data); // [-10, -0.5, 0, 2, 3] function desiredComparison(a,b){ return a-b; }
自分の好きな順番で並び替える
上記のロジックを、英語の月を例に組み替えてみます。
自分の好きな順序を定義した配列(desiredSort)との位置関係を利用するのがポイントです。
let desiredSort = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] function desiredComparison(a,b){ let posa,posb; if(desiredSort.indexOf(a)){ posa = desiredSort.indexOf(a); }else{ posa = desiredSort.length; } if(desiredSort.indexOf(b)){ posb = desiredSort.indexOf(b); }else{ posb = desiredSort.length; } return posa-posb; }
ここではまずindexOf()を用いて、引数a,bがそれぞれdesiredSortで何番目の要素か?を取得しています。desiredSortに要素があればそのインデックス番号を、なければインデックス外の値(ここではdesiredSortのlength)を、それぞれposa,posb変数に格納します。
そして、
- posa(aの位置)がposb(bの位置)よりも小さければ「負の値」,
- posb(bの位置)がposa(aの位置)よりも大きければ「正の値」,
- 同じであれば0
をそれぞれ返却します。この例では先ほどの昇順の例と同じく、posaとposbの差分を返しています。
これで自分の好きな順番で配列の要素を並び替えることができました。
let data = ["November","February","August"]; data.sort(desiredComparison); console.log(data); // ["February","August","November"]