JavaScriptで配列のソートを行うには、配列.sort()メソッドを使うのが手っ取り早い。ただ条件(正確には比較関数)の書き方が簡単そうで難しい。
配列.sort()の基本的な使い方
JavaScriptの配列のsort()メソッドは、UTF-16のコードポイントの値に基づいて昇順でソートを行う。これは、元の配列をコピーせずに並び替える破壊的操作である。
並び替えはその場で行われるため、メモリはほとんど消費されない。また、返される値は並び替えが終わった同じ配列の参照である。
ちなみに元の配列を破壊せずにソートしたい時はtoSorted()メソッドを使う。
注意したいのは、いずれの場合も2桁以上の整数を正しくソートできない点である。UTF-16では、数値もアルファベットも昇順に文字コードが割り振られている。
ただ、両者のデフォルトの比較関数は、1文字単位で並び替えを行うため、2よりも10の方が小さいと判断されてしまう。
整数を比較したいときは、並び替え方法を別途指定する必要がある。
並び替え方法の指定
sort()メソッドのソート方法をコントロールするには、引数に比較用の関数を渡せばよい。
この関数は、引数に2つの値を受け取る。これは配列の前後の要素である。関数内でこれら2つの値をあれこれして、正負、あるいは0のいずれかで値を返すと、sort()メソッドがいい感じに並び替えをしてくれる。
例えばaとbを引数に受け取ったとすると、返す値によってソートのパターンは以下のように決定される。
- 正のとき:
aをbの後ろに並び替える。 - 負のとき:
aをbの前に並び替える。 0のとき:aとbの元々の順番を維持する。
混乱するポイント
a - bの場合、その結果が負のときは「aの方が小さい」、と判断する。正のときは「aの方が大きい」、と判断する。どちらのケースも、現在の並び順に応じて、昇順に並び替えを行う。
b - aの場合、その結果が負のときは「bの方が小さい」、と判断する。正のときは「bの方が大きい」、と判断する。どちらのケースも、現在の並び順に応じて、昇順に並び替えを行う。
a - bと、b - aで、何がちがうの? と混乱するかもしれない。書いていて自分でも混乱した。何がちがうかといえば、符合が違う。そのため大小が逆転し、アルゴリズムが同じでもソートの昇順と降順が入れ替わる。
文字列を任意の順番にソートする
JavaScriptの配列のsort()メソッドを使ったソートは、比較関数が返す正負あるいは0の値によって決定される。
そのため、文字列の配列を任意の順番に並び替えたいときは、数値ベースで処理できるよう事前に準備してやるのが早道である。
例えば月名を並び替える処理は、以下のようになる。
おしまい。