みかづきブログ・カスタム

基本的にはちょちょいのほいです。

JavaScriptで日本語を五十音順にソートする 🇯🇵

f:id:kimizuka:20210603121442p:plain

String.prototype.localeCompare という非常に便利なメソッドを発見しました。引数に'ja'を渡しつつ、Array.prototype.sortと組み合わせることで、日本語を五十音順にソートすることができるようです。

developer.mozilla.org

[
  'オギノ',
  'マーティン',
  'ナカムラ',
  'レアード',
  'カクナカ',
  'イノウエ',
  'フジオカ',
  'サトウ',
  'イワシタ'
].sort((a, b) => a.localeCompare(b), 'ja'); // => ['イノウエ', 'イワシタ', 'オギノ', 'カクナカ', 'サトウ', 'ナカムラ', 'フジオカ', 'マーティン', 'レアード']

すべてが、ひらがな、カタカナで統一されていれば五十音順にソートしてくれます。

[
  'おぎの',
  'マーティン',
  'なかむら',
  'レアード',
  'かくなか',
  'いのうえ',
  'ふじおか',
  'さとう',
  'いわした'
].sort((a, b) => a.localeCompare(b), 'ja'); // => ['いのうえ', 'いわした', 'おぎの', 'かくなか', 'さとう', 'なかむら', 'ふじおか', 'マーティン', 'レアード']

ひらがな、カタカナが混ざっている場合は、まずはひらがなを五十音順にソートし、そのあとにカタカナを五十音順にソートします。

この挙動について調べてみたところ、

1. 記号
2. 数字
3. アルファベット(全角含む)
4. ひらがな
5. カタカナ
6. 漢字

の順にソートされるようです。

また、

[
  '荻野',
  'マーティン',
  '中村',
  'レアード',
  '角中',
  '井上',
  '藤岡',
  '佐藤',
  '岩下'
].sort((a, b) => a.localeCompare(b), 'ja'); // => ['マーティン', 'レアード', '井上', '荻野', '角中', '岩下', '佐藤', '中村', '藤岡']

漢字も音読みでソートされるようで、「岩下」の位置がおかしいです。たぶん「いわ」ではなく「がん」でソートされているのだと思われます。
昔のiTunesがこんな感じだった気がします。

なので、実戦で使う場合はひらがなかカタカナで読み仮名を統一して、それをソートに使うのが良さそうです。

[
  { name: '荻野', ruby: 'おぎの' },
  { name: 'マーティン', ruby: 'まーてぃん' },
  { name: '中村', ruby: 'なかむら' },
  { name: 'レアード', ruby: 'れあーど' },
  { name: '角中', ruby: 'かくなか' },
  { name: '井上', ruby: 'いのうえ' },
  { name: '藤岡', ruby: 'ふじおか' },
  { name: '佐藤', ruby: 'さとう' },
  { name: '岩下', ruby: 'いわした' }
].sort((a, b) => a.ruby.localeCompare(b.ruby), 'ja'); // => [{ name: '井上', ruby: 'いのうえ' }, { name: '岩下', ruby: 'いわした' }, { name: '荻野', ruby: 'おぎの' }, { name: '角中', ruby: 'かくなか' }, { name: '佐藤', ruby: 'さとう' }, { name: '中村', ruby: 'なかむら' }, { name: '藤岡', ruby: 'ふじおか' }, { name: 'マーティン', ruby: 'まーてぃん' }, { name: 'レアード', ruby: 'れあーど' }]