やりたいこと
文字列(主にファイル名)の配列をWindowsのファイル名ソートと同じようにソートします。
背景
単純に以下のようにソートをした場合の結果を見てみます。
コード:
filenames.sort();
入力:
filenames = ["10","1","2","a","A","b","B","い","ア","あ"]
結果:
['1', '10', '2', 'A', 'B', 'a', 'b', 'あ', 'い', 'ア']
このソートだと文字コードの大小でソートが行われます。
そのため数字は”1”,”2”,”10”と並んでほしいのですが、”1”,”10”,”2”とならびます。
またひらがなカタカナ、アルファベットも感覚と異なるソート結果が返ってきます。
実装
以下の実装でWindowsのファイル名と同様(完全に同じかは未検証ですが漢字の並びも含めて違いは見つけられませんでした。)のソートが行えます。
コード:
const collator = new Intl.Collator('ja-JP', { numeric: true, sensitivity: 'base' });
filenames.sort(collator.compare);
入力:
filenames = ["10","1","2","a","A","b","B","い","ア","あ"]
結果:
['1', '2', '10', 'A', 'a', 'B', 'b', 'あ', 'ア', 'い']
数字は”1”,”2”,”10”と並んでほしいの順序と同じく、”1”,”10”,”2”とならびます。
またひらがなカタカナ、アルファベットも感覚に近いソートがされています。
‘ja-JP’は使用する文字列のキャラクターセットによって変更してください。
実際の実装
実際にはファイル名の配列をソートすることはなく、ファイル名を持つファイルオブジェクトをソートすることがほとんどだと思います。
ファイル名をもつオブジェクトの配列をソートするには以下のようになります。(filesがファイル名を字格納するnameを持つオブジェクトの配列)
const collator = new Intl.Collator('ja-JP', { numeric: true, sensitivity: 'base' });
files.sort((a, b) => collator.compare(a.name, b.name));
コメント