●Array.prototype.sortメソッドとは?
JavaScriptの配列を扱う上で、Array.prototype.sortメソッドは非常に重要な役割を果たします。
このメソッドを使えば、数値や文字列の配列を簡単に並べ替えることができるのです。
例えば、商品の価格を安い順に表示したいとき、ユーザーの名前をアルファベット順に並べたいとき、あるいはゲームのスコアを高い順に表示したいとき。
こういったシーンでArray.prototype.sortメソッドが大活躍します。
sortメソッドは配列自体を直接変更し、並べ替えられた配列を返します。
つまり、元の配列の順序が変更されるということですね。
ただ、そのまま使うと思わぬ結果になることがあるので、正しく使いこなすためにはいくつかポイントを押さえておく必要があります。
○sortメソッドの基本的な使い方
では早速、sortメソッドの基本的な使い方を見ていきましょう。
sortメソッドは、引数なしで呼び出すと、配列の要素を文字列に変換した上で、UTF-16コード単位の値の順序で並べ替えを行います。
つまりデフォルトでは、数値も文字列として扱われるということですね。
次のサンプルコードを見てみましょう。
○サンプルコード1:デフォルトのソート
実行結果
数値の配列に対してsortメソッドを呼び出すと、期待通りの結果が得られました。
数字が昇順に並べ替えられていますね。
でも、次の例はどうでしょうか。
実行結果
数値としては正しくソートされていないようです。
これは、先ほど述べたように、デフォルトでは要素を文字列として扱うためです。
文字列の「1」、「2」、「3」、「4」の順になっているのがわかりますね。
数値をきちんと並べ替えるには、sortメソッドに比較関数を渡す必要があります。
○サンプルコード2:数値のソート
実行結果
比較関数(a, b) => a - b
を渡すことで、数値が正しい順序でソートされました。
この比較関数は、2つの要素a
とb
を受け取り、a - b
の結果が負ならa
を先に、正ならb
を先に並べるという意味です。
○サンプルコード3:文字列のソート
文字列の配列も、デフォルトのsortメソッドで並べ替えることができます。
実行結果
アルファベット順に並べ替えられていますね。
ただ、このデフォルトの動作はUTF-16コード単位の値に基づいているので、常に期待通りの結果が得られるわけではありません。
例えば、アクセント記号付きの文字を含む場合や、大文字と小文字が混在する場合などです。
こういったケースでは、適切な比較関数を用意する必要があります。
localeCompareメソッドを使うのも一つの方法ですね。
●ソート順のカスタマイズ
デフォルトのソート順が期待通りにならないケースは意外と多いものです。
例えば、数値の配列を並べ替えるときに文字列として扱われてしまったり、大文字と小文字が混在する文字列の配列で思わぬ結果になったり。
Array.prototype.sortメソッドには、ソート順をカスタマイズする方法がちゃんと用意されているんです。
○サンプルコード4:昇順と降順の切り替え
ソートのデフォルトは昇順ですが、降順に並べ替えたい場合もありますよね。
そんな時は、比較関数を工夫することで簡単に切り替えられます。
実行結果
比較関数でa - b
とすれば昇順、b - a
とすれば降順になるわけです。
これは、比較関数が正の値を返せばb
を先に、負の値を返せばa
を先に並べるという仕組みを利用しています。
○サンプルコード5:独自の比較関数の使用
比較関数を自分で定義すれば、より複雑なソート順のルールを実現できます。
例えば、文字列の長さを基準に並べ替えるなんてことも可能です。
実行結果
比較関数で各文字列の長さを比べることで、文字列の長さ順にソートされました。
○サンプルコード6:オブジェクトのソート
配列の要素がオブジェクトだった場合、特定のプロパティを基準にソートしたいということもあるでしょう。
実行結果
比較関数の中で、オブジェクトのage
プロパティを比較することで、年齢順にソートができました。
同じ要領で、他のプロパティを基準にソートすることも可能ですね。
比較関数を使いこなせば、ソート順のカスタマイズは思いのままです。
配列の要素の型に合わせて適切な比較方法を選ぶことが大切ですね。
●よくあるエラーと対処法
Array.prototype.sortメソッドを使っていると、時々思わぬエラーに遭遇することがあります。
初心者の頃は特に、エラーメッセージを見てもどこが悪いのかわからなくて困ってしまうものです。
ここでは、sortメソッドを使う際によく出くわすエラーとその対処法を見ていきましょう。
エラーの原因を理解して、正しくソートを行えるようになりましょう。
○”TypeError: arr.sort is not a function”
このエラーは、sortメソッドを呼び出そうとしているオブジェクトが配列ではない場合に発生します。
例えば、次のようなコードではエラーが起きてしまいます。
実行結果
文字列の'hello'
は配列ではないので、sortメソッドを持っていません。
エラーを避けるには、sortメソッドを呼び出す前に、対象が本当に配列であるかを確認する必要があります。
Array.isArray()
メソッドを使うのが一般的ですね。
こうすれば、配列ではないオブジェクトに対してsortメソッドを呼び出すことはなくなります。
○比較関数が正しく動作しない
比較関数の書き方を間違えると、期待通りのソート結果が得られないことがあります。
例えば、数値の配列を昇順にソートするつもりで、次のような比較関数を書いたとします。
実行結果
期待した昇順になっていません。
比較関数の戻り値は、負の値、0、正の値のいずれかである必要があります。
この例では、a
とb
が等しい場合の戻り値を指定していないため、正しくソートできていないのです。
比較関数は、a
がb
より小さい場合は負の値、等しい場合は0、大きい場合は正の値を返すように書きましょう。
実行結果
これで正しくソートされました。
比較関数の仕様をしっかり理解して、適切な戻り値を返すようにしましょう。
○ソート結果が予期しない順序になる
文字列の配列をソートする際、大文字と小文字が混在していると予期しない順序になることがあります。
実行結果
デフォルトのソートでは、大文字が小文字よりも先に来てしまいます。
これを避けるには、比較関数の中で大文字と小文字を区別しないように処理を行う必要があります。
localeCompare()
メソッドを使うのが簡単です。
実行結果
localeCompare()
メソッドは、文字列を言語に依存した方法で比較し、適切な順序で並べ替えてくれます。
●sortメソッドの応用例
さて、ここまでArray.prototype.sortメソッドの基本的な使い方やカスタマイズ方法を見てきましたが、実際の開発現場ではもっと様々な場面でソートを活用しています。
ちょっとややこしいですが、sortメソッドを使った応用例をいくつか見ていきましょう。
きっと、配列操作の幅が広がるはずです。
○サンプルコード7:重複要素の削除
配列から重複する要素を取り除きたい場合、ソートを活用することができます。
まず配列をソートし、隣り合う要素を比較していくことで、重複をスキップできるのです。
実行結果
ソートした後、filter()
メソッドを使って隣り合う要素を比較しています。
先頭の要素(i === 0
)と、1つ前の要素と異なる場合だけtrue
を返すようにすれば、重複が取り除かれた配列が得られます。
○サンプルコード8:ランダムな順序へのシャッフル
配列の要素をランダムな順序に並び替えたい場合は、Math.random()
を使った比較関数を利用できます。
実行結果(例)
Math.random() - 0.5
は、-0.5から0.5の範囲の値をランダムに返します。
これを比較関数として使うことで、要素がランダムに並び替えられます。
○サンプルコード9:複数のプロパティを用いたソート
オブジェクトの配列を複数のプロパティに基づいてソートしたい場合は、比較関数の中で条件分岐を使います。
実行結果
まずはage
プロパティで昇順にソートし、age
が同じ場合はcity
プロパティでソートしています。
city
の比較にはlocaleCompare()
メソッドを使っていますね。
○サンプルコード10:日本語の文字列のソート
日本語の文字列を配列にソートする場合、localeCompare()
メソッドに適切なロケールを指定する必要があります。
実行結果
localeCompare()
メソッドの第2引数に'ja'
を指定することで、日本語に適した方法で文字列を比較し、正しい順序で並べ替えることができます。
まとめ
JavaScriptのArray.prototype.sortメソッドは、配列のソートを行う強力な機能です。
デフォルトの動作をよく理解し、比較関数を適切に使いこなすことが大切です。
ソートに関連するエラーへの対処法を身につけることで、より安定したコードを書けるようになるでしょう。
また、応用的な使い方を知ることで、柔軟な配列操作が可能となります。
sortメソッドをマスターすれば、配列データを自在に扱えるようになります。
基本をしっかりと押さえつつ、徐々に応用範囲を広げていきましょう。