組み込み関数

JavaScriptのsort()入門|配列の並べ替えを完全理解する

sort()は、配列の要素を並べ替えるメソッドです。文字列の辞書順ソートだけでなく、比較関数を指定することで数値の昇順・降順やオブジェクトのプロパティ順など、柔軟な並べ替えが可能です。元の配列を直接変更する点に注意が必要です。

基本的な使い方

引数なしでsort()を呼ぶと、要素を文字列に変換してUTF-16コードポイント順で並べ替えます。数値の配列では意図しない結果になるため、比較関数の指定が重要です。

JavaScript
// 文字列のソート(デフォルト)
const fruits = ["バナナ", "りんご", "みかん", "いちご"];
fruits.sort();
console.log(fruits);

// 数値のソート(デフォルトだと文字列順になる)
const numbers = [10, 5, 40, 25, 1, 100];
numbers.sort();
console.log(numbers); // 文字列順: "1", "10", "100", "25"...

// 比較関数で正しく数値ソート
const nums = [10, 5, 40, 25, 1, 100];
nums.sort((a, b) => a - b);
console.log(nums);
実行結果
["いちご", "バナナ", "みかん", "りんご"]
[1, 10, 100, 25, 40, 5]
[1, 5, 10, 25, 40, 100]

比較関数は2つの要素abを受け取り、戻り値が負ならaを前に、正ならbを前に、0なら順序を変えません。a - bで昇順、b - aで降順になります。

オブジェクト配列のソート

実務では、オブジェクトの配列を特定のプロパティで並べ替える場面が非常に多いです。比較関数の中でプロパティにアクセスすることで実現できます。

JavaScript
const employees = [
  { name: "田中", age: 28, salary: 350000 },
  { name: "佐藤", age: 35, salary: 520000 },
  { name: "鈴木", age: 24, salary: 280000 },
  { name: "高橋", age: 31, salary: 450000 }
];

// 年齢の昇順でソート
const byAge = [...employees].sort((a, b) => a.age - b.age);
console.log(byAge.map(e => `${e.name}(${e.age})`));

// 給与の降順でソート
const bySalary = [...employees].sort((a, b) => b.salary - a.salary);
console.log(bySalary.map(e => `${e.name}: ¥${e.salary.toLocaleString()}`));

// 名前の五十音順でソート
const byName = [...employees].sort((a, b) => a.name.localeCompare(b.name, "ja"));
console.log(byName.map(e => e.name));
実行結果
["鈴木(24)", "田中(28)", "高橋(31)", "佐藤(35)"]
["佐藤: ¥520,000", "高橋: ¥450,000", "田中: ¥350,000", "鈴木: ¥280,000"]
["佐藤", "鈴木", "高橋", "田中"]

スプレッド演算子[...]でコピーを作成してからソートすることで、元の配列を変更せずに並べ替えた新しい配列を取得できます。日本語の文字列を正しく並べ替えるにはlocaleCompare()を使います。

実践的な活用例

複数の条件でソートする方法や、安定ソートの活用を紹介します。

JavaScript
// 複数条件でソート(部署順 → 年齢順)
const staff = [
  { name: "田中", dept: "開発", age: 28 },
  { name: "佐藤", dept: "営業", age: 35 },
  { name: "鈴木", dept: "開発", age: 32 },
  { name: "高橋", dept: "営業", age: 27 },
  { name: "伊藤", dept: "開発", age: 25 }
];

staff.sort((a, b) => {
  // まず部署で比較
  const deptCompare = a.dept.localeCompare(b.dept, "ja");
  if (deptCompare !== 0) return deptCompare;
  // 同じ部署なら年齢で比較
  return a.age - b.age;
});

staff.forEach(s => console.log(`${s.dept} - ${s.name}(${s.age})`));

// toSorted() - 元の配列を変更しない新しいメソッド(ES2023)
const original = [3, 1, 4, 1, 5];
const sorted = original.toSorted((a, b) => a - b);
console.log("元の配列:", original);
console.log("ソート後:", sorted);
実行結果
営業 - 高橋(27)
営業 - 佐藤(35)
開発 - 伊藤(25)
開発 - 田中(28)
開発 - 鈴木(32)
元の配列: [3, 1, 4, 1, 5]
ソート後: [1, 1, 3, 4, 5]
toSorted()について

ES2023で追加されたtoSorted()は、元の配列を変更せずにソート済みの新しい配列を返します。イミュータブルな操作が必要な場合はtoSorted()の使用を検討してください。

注意点

sort()は元の配列を直接変更します(破壊的操作)。元の順序を保持したい場合は、必ず[...array].sort()array.slice().sort()でコピーしてからソートしてください。また、比較関数を省略した数値ソートは文字列順になるため、必ず(a, b) => a - bを指定しましょう。

まとめ

  • sort()は配列を並べ替えるメソッドで、元の配列を直接変更する
  • 数値ソートには必ず比較関数(a, b) => a - bを指定する
  • 日本語のソートにはlocaleCompare()を使う
  • 複数条件のソートは比較関数内で順番に判定する
  • ES2023のtoSorted()で非破壊的なソートが可能