配列のソート - sort, toSorted

《 初回公開:2023/10/19 , 最終更新:未 》

配列の要素をソートするには、破壊的メソッドであるsortメソッドと非破壊的メソッドであるtoSortedメソッドがある。

【 目次 】

sort

配列の要素をソートする破壊的メソッド。

構文
array.sort([compareFn])
引数
compareFn (オプション)

要素間の比較を行う関数。省略された場合、要素は文字列としてソートされる。
compareFnは以下の引数を持つ。

a
比較対象の要素。
b
比較対象の別の要素。
戻り値
元の配列の要素をソードしてその元の配列の参照を返す

引数compareFnが省略された場合、配列のundefined 以外の各要素は文字列に変換され、UTF-16コード単位の値の並びとしてソートされる。
undefined の要素はすべて、配列の末尾に並べられる。
UTF-16コード単位なので、コードポイントが\uFFFF を超える文字はサロゲートペアに変換されて\uFFFFより前に並べられるようだ。

JavaScriptの文字コードについては

引数compareFnが指定された場合、compareFnの戻り値に基づいて、ソートの順序が決定る。
即ち。

  • compareFunction(a, b) の結果が負の値である場合、a は b よりも前にソートされる。
  • compareFunction(a, b) の結果がゼロである場合、a と b の順序は変更されない。
  • compareFunction(a, b) の結果が正の値である場合、a は b よりも後にソートされる。

シンプルにcompareFn関数を省略してsortメソッドを実行した場合、文字列に変換した後の昇順でソートされる。

// 文字列の順で昇順でソート
const array = [5, 3, 40, 401];
const result = array.sort();
console.log(result);    // [3, 40, 401, 5]

数値の昇順としてソートするにはcompareFn関数を使って。

// 数値のまま昇順でソート
const array = [5, 3, 40, 401];
array.sort((a, b) => a - b);
console.log(array); // [3, 5, 40, 401]

降順でソートするにはcompareFn関数を変更して。

array.sort((a, b) => b - a);

空のスロットの要素はすべて、配列の末尾に並べられるので、空スロットを含む配列を昇順でソートすると。

// 空スロットを含む配列を昇順でソート
const array = [5, 3, , 40, 401];
array.sort((a, b) => a - b);
console.log(array); // [3, 5, 40, 401, なし]

文字列のソートはUTF-16(16bit単位のコードユニット)の順順でソートされる

const array = ["5", "あ", "ア", "a", "A", "a", "A"];
array.sort();
console.log(array); // ['5', 'A', 'a', 'あ', 'A', 'a', 'ア']

UTF-16の順順でソートされるのでサロゲートペアの文字を含む文字列では必ずしもコードポイント順にはならない。

// U+2000B 𠀋 と F9600 怒
const array = ["𠀋", "怒"];
// UTF16でソート
array.sort();
console.log(array); // ["𠀋", "怒"];

これをコードポイント順にソートするには。

const array = ["𠀋", "怒"];
// コードポイント順にソート
array.sort(function (a, b) {
    const codePointA = a.codePointAt();
    const codePointB = b.codePointAt();
    console.log(`${a}(0x${codePointA.toString(16)}), ${b}(0x${codePointB.toString(16)}), ${codePointA - codePointB}`);
    // 怒(0xf960), 𠀋(0x2000b), -67243
    return codePointA - codePointB;
});
console.log(array); // ['怒', '𠀋']

toSorted

配列の要素をソートする非破壊的メソッド。

構文
array.toSorted([compareFn])
引数
compareFn (オプション)

要素間の比較を行う関数。省略された場合、要素は文字列としてソートされる。
compareFnは以下の引数を持つ。

a
比較対象の要素。
b
比較対象の別の要素。
戻り値
元の配列の要素をソードしてその元の配列の参照を返す

sortが破壊的メソッドであるのに対してtoSortedは非破壊的メソッドであり元の配列を変更しない。

{
    // sortメソッドは元の配列を変更する
    const array = [5, 3, 40, 401];
    const result = array.sort();
    console.log(array, result); // [3, 40, 401, 5] [3, 40, 401, 5]
}
{
    // toSortedメソッドは元の配列を変更しない
    const array = [5, 3, 40, 401];
    const result = array.toSorted();
    console.log(array, result); // [5, 3, 40, 401] [3, 40, 401, 5]
}

空のスロットの要素はすべて、配列の末尾に並べられ、undefinedに、それ以外はsortメソッドと同じ動作。

// 空スロットを含む配列を昇順でソート
const array = [5, 3, , 40, 401];
const result = array.toSorted((a, b) => a - b);
console.log(result);    // [3, 5, 40, 401, undefined]

UTF-16の順順でソートされるのでサロゲートペアの文字を含む文字列では必ずしもコードポイント順にはならない。

// U+2000B 𠀋 と F9600 怒
const array = ["𠀋", "怒"];
// UTF16でソート
const result = array.toSorted();
console.log(result);    // ["𠀋", "怒"];
ページのトップへ戻る