【JavaScript】数字と英字が混在する配列を自然な順序でソートする方法
英数字混在配列のソートとは
まず、次のような英字と数字が混ざった文字列の配列を想定してみましょう。
const arr = ['A1', 'A10', 'A11', 'A12', 'A3A', 'A3B', 'A3', 'A4', 'B10', 'B2', 'F1', '1', '2', 'F3'];
この配列を唯一の引数として受け取り、元の配列自身(インプレース)を並べ替えるJavaScript関数を作成します。ソートのルールは以下のとおりです。
- 数字だけで構成される文字列は先頭に集め、昇順で並べる。
- 英字と数字が組み合わさった文字列は、まず英字の順に、同じ英字の場合は続く数字の昇順で並べる。
つまり、期待される出力は次のようになります。
const output = ['1', '2', 'A1', 'A3', 'A3A', 'A3B', 'A4', 'A10', 'A11', 'A12', 'B2', 'B10', 'F1', 'F3'];
これはいわゆる自然順ソート(ナチュラルソート)の一種です。単純に String.prototype.sort() を使うと辞書順比較になるため、「A10」が「A3」より前に来てしまうといった問題が発生します。そこで、文字列を適切な単位に分解して比較する専用の比較関数が必要になります。
実装例
const arr = ['A1', 'A10', 'A11', 'A12', 'A3A', 'A3B', 'A3', 'A4', 'B10', 'B2', 'F1', '1', '2', 'F3'];
const alphaNumericSort = (arr = []) => {
const sorter = (a, b) => {
// 純粋な数字文字列かどうかを判定するヘルパー関数
const isNumber = (v) => (+v).toString() === v;
// 文字列を「数字の連続」と「数字以外の連続」に分割
const aPart = a.match(/\d+|\D+/g);
const bPart = b.match(/\d+|\D+/g);
let i = 0;
const len = Math.min(aPart.length, bPart.length);
// 共通する部分を読み飛ばす
while (i < len && aPart[i] === bPart[i]) { i++; }
// 片方がもう片方の接頭辞になっている場合は短い方を先に
if (i === len) {
return aPart.length - bPart.length;
}
// 比較対象がどちらも数字なら数値として大小を比較
if (isNumber(aPart[i]) && isNumber(bPart[i])) {
return aPart[i] - bPart[i];
}
// それ以外は文字列として比較
return aPart[i].localeCompare(bPart[i]);
};
arr.sort(sorter);
};
alphaNumericSort(arr);
console.log(arr);コードのポイント解説
この実装の仕組みを簡単に整理すると、次の3ステップで構成されています。
- 分割処理: 正規表現
/\d+|\D+/gを使うことで、「A10」なら['A', '10']のように、英字部分と数字部分にきれいに分離できます。 - 数値としての比較: 分割後の要素が両方とも数字であれば、
aPart[i] - bPart[i]によって数値の大小で比較されます。これにより「A3」が「A10」より前になる自然な並びが実現します。 - 文字列としての比較: 英字同士の比較には
localeCompare()を使用しているため、ロケールを考慮した安定した文字列比較が可能です。
出力結果
コンソールに出力される結果は以下のとおりです。
[ '1', '2', 'A1', 'A3', 'A3A', 'A3B', 'A4', 'A10', 'A11', 'A12', 'B2', 'B10', 'F1', 'F3' ]
まとめ
ファイル名や製品型番のように「英字+数字」が混在するデータを扱う場面では、標準の辞書順ソートでは意図した順序になりません。本記事のように文字列を正規表現で分割し、数字部分は数値比較・英字部分は文字列比較を行うカスタム比較関数を実装することで、人間にとって直感的な自然順ソートを簡単に実現できます。ぜひ実務でも活用してみてください。
-
JavaScriptで挿入ソートを実装する方法をわかりやすく解説
挿入ソート(Insertion Sort)とは挿入ソートは、配列を並べ替えるための非常にシンプルな比較ソートの一つです。比較ソートでは、現在ソートしようとしている値を配列内の他の値と順番に比較しながら、1つの要素ずつ処理を進めます。各要素を正しい位置へ繰り返し挿入していくことで、最終的にソート済みの配列を作り上げます。実際のところ、挿入ソートはヒープソートやマージソートといった高度なアルゴリズムほど効率的ではありません。そのため、大規模なデータを扱う場合には必ずしも最適な選択肢とは言えません。しかし、隠れた定数項が小さいという特性を持つため、小さな配列を扱う場面では、ヒープソートやクイックソー
-
JavaScriptのArray.prototype.sort()メソッドの使い方をサンプルコードで解説
Array.prototype.sort()は、JavaScriptで配列の要素を並べ替えるための組み込みメソッドです。アルファベット順・数値順といった並び方に加えて、昇順・降順も自由に指定でき、配列操作の中でも特に使用頻度の高いメソッドの一つです。 ただし重要なポイントとして、sort()メソッドはデフォルトではすべての要素を文字列に変換してから比較します。そのため、数値の配列を意図したとおりに並べ替えたい場合は、比較関数を引数として渡す必要があります。 以下は、Array.prototype.sort()メソッドの基本的な使い方を示すサンプルコードです。 サンプルコード <!DOC