【JavaScript】文字列の自然なソート!localeCompareで大文字・小文字を正しく並べる

目次

概要

配列を sort() で並べ替える際、英単語のリストに大文字と小文字が混在していると、予期しない順序になることがあります(例: “apple” よりも “Zebra” が先に来る)。これはコンピュータが文字コード順(ASCII順)で判断しているためです。

人間にとって自然な「辞書順(あいうえお順、ABC順)」で並べ替えるには、文字列専用の比較メソッド localeCompare を使用します。本記事では、このメソッドを使って都市名リストを正しく並べ替える方法を解説します。

仕様(入出力)

localeCompare メソッド

基準となる文字列と、引数で渡された文字列を比較し、並び順を数値で返します。

メソッド意味戻り値 (数値)sortでの挙動
strA.localeCompare(strB)strAstrB を辞書順で比較する。負の値 (-1)strA に配置
正の値 (1)strA に配置
0順序を変えない
  • 入力: 比較対象の文字列
  • 出力: ソート順を示す数値 (-1, 0, 1)

基本の使い方

デフォルトの sort()localeCompare の違い

デフォルトでは大文字(A-Z)が小文字(a-z)よりも優先されますが、localeCompare を使うとこれを無視してアルファベット順にできます。

const words = ['apple', 'Banana', 'cherry'];

// 1. 普通にsort (大文字が優先される)
words.sort();
console.log(words); 
// ["Banana", "apple", "cherry"]  <-- "B"は"a"よりコードが若いため先頭に来る

// 2. localeCompareを使用 (辞書順)
words.sort((a, b) => a.localeCompare(b));
console.log(words); 
// ["apple", "Banana", "cherry"]  <-- 大文字小文字関係なくA->B->C順になる

コード全文(HTML / JavaScript)

海外の都市名リストを並べ替えるデモです。

入力データの表記揺れ(大文字・小文字の混在)があっても、正しくABC順に整列させます。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>City List Sort</title>
    <style>
        .sort-panel {
            font-family: 'Segoe UI', sans-serif;
            max-width: 500px;
            padding: 20px;
            border: 1px solid #ccc;
            border-radius: 8px;
            background-color: #f9f9f9;
        }
        .btn-group {
            margin-bottom: 15px;
            display: flex;
            gap: 10px;
        }
        button {
            padding: 10px 15px;
            cursor: pointer;
            border: 1px solid #999;
            background-color: #fff;
            border-radius: 4px;
        }
        button:hover { background-color: #eee; }
        
        .list-area {
            background: white;
            border: 1px solid #ddd;
            padding: 10px;
            min-height: 100px;
        }
        ul { margin: 0; padding-left: 20px; }
        li { padding: 4px 0; border-bottom: 1px dashed #eee; }
        .note { font-size: 0.85rem; color: #666; margin-bottom: 10px; }
    </style>
</head>
<body>

<div class="sort-panel">
    <h3>都市名リスト並べ替え</h3>
    <p class="note">データ: ['london', 'Paris', 'austin', 'Tokyo', 'berlin']</p>
    
    <div class="btn-group">
        <button id="btn-default">デフォルトSort (ASCII順)</button>
        <button id="btn-locale">localeCompare (辞書順)</button>
    </div>

    <div class="list-area">
        <ul id="city-list">
            </ul>
    </div>
</div>

<script src="city_sort.js"></script>
</body>
</html>

JavaScript

/**
 * 都市名ソートスクリプト
 * 文字列の比較ロジックの違いを検証
 */

// 1. ソート対象のデータ
// わざと大文字と小文字を混在させています
let cities = ['london', 'Paris', 'austin', 'Tokyo', 'berlin'];

// DOM要素
const listElement = document.getElementById('city-list');
const btnDefault = document.getElementById('btn-default');
const btnLocale = document.getElementById('btn-locale');

/**
 * リストを描画する関数
 */
const renderList = () => {
    listElement.innerHTML = '';
    cities.forEach(city => {
        const li = document.createElement('li');
        li.textContent = city;
        listElement.appendChild(li);
    });
};

/**
 * デフォルトのソート (文字コード順)
 * 大文字(A-Z) -> 小文字(a-z) の順になる
 */
const sortDefault = () => {
    // 文字列のデフォルトソート
    cities.sort();
    renderList();
};

/**
 * localeCompareを使ったソート (辞書順)
 * 大文字小文字を区別せず、アルファベット順になる
 */
const sortLocale = () => {
    cities.sort((a, b) => {
        // a と b を自然言語のルールで比較する
        return a.localeCompare(b);
    });
    renderList();
};

// 初期表示
renderList();

// イベント設定
btnDefault.addEventListener('click', sortDefault);
btnLocale.addEventListener('click', sortLocale);

カスタムポイント

  • 日本語のソート:日本語(ひらがな・カタカナ・漢字)を正しく並べ替えたい場合は、第2引数にロケールコード 'ja' を指定します。JavaScript// 日本語環境でのソートを明示 list.sort((a, b) => a.localeCompare(b, 'ja')); ※ただし、漢字の「読み(音読み・訓読み)」までは判定できないため、正確な50音順にするには別途「フリガナ」データが必要です。
  • 数値混じりのソート:File1, File10, File2 のような文字列を File1, File2, File10 と並べたい場合(Natural Sort)、第3引数オプションを使用します。JavaScripta.localeCompare(b, undefined, { numeric: true })

注意点

  1. ブラウザの対応状況localeCompare は非常に便利なメソッドですが、大量のデータ(数万件以上)をソートする場合、単純な比較演算子(> <)よりも処理速度が遅くなる傾向があります。数千件レベルであれば無視できる差ですが、パフォーマンスがクリティカルな場面では注意してください。
  2. 破壊的メソッドここでも sort を使用しているため、元の配列 cities の並び順が変更されます。元データを保持したい場合は、[...cities].sort(...) とコピーしてから実行してください。

応用

逆順(降順)にしたい場合

localeCompare の呼び出し元と引数を入れ替えるだけです。

// 昇順 (A -> Z)
cities.sort((a, b) => a.localeCompare(b));

// 降順 (Z -> A)
cities.sort((a, b) => b.localeCompare(a));

まとめ

ユーザー名や商品名など、テキストデータを人間に見やすい順序で並べる場合は、必ず localeCompare を使用しましょう。

  • sort() そのまま: コンピュータ都合の順序(大文字優先)。
  • localeCompare: 人間都合の順序(辞書順)。

この使い分けが、使いやすいUIを作る第一歩です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次