JavaScript 逆引き集 | 配列のソート(数値)

JavaScript JavaScript
スポンサーリンク

JavaScript配列のソート(数値)の基本と実践

数値配列を正しく並べ替えるには、比較関数を渡して「数値として」比較させるのがポイントです。デフォルトのsortは文字列として比較するため、数値だと期待通りの順序になりません。


構文と考え方

// 昇順(小さい→大きい)
arr.sort((a, b) => a - b);

// 降順(大きい→小さい)
arr.sort((a, b) => b - a);
JavaScript
  • 比較関数: 返り値が0未満ならaが先、0なら同順、0より大ならbが先。
  • 破壊的変更: sortは元の配列を書き換えます。元を残したい場合はコピーしてから。
const sorted = [...arr].sort((a, b) => a - b); // 安全(元は保持)
JavaScript

すぐ使えるテンプレート集

基本の昇順・降順

const nums = [1, 2, 10, 3, 5];

// 昇順
nums.sort((a, b) => a - b);
console.log(nums); // [1, 2, 3, 5, 10]

// 降順
nums.sort((a, b) => b - a);
console.log(nums); // [10, 5, 3, 2, 1]
JavaScript
  • ポイント: 文字列比較の落とし穴([1, 2, 10] → [1, 10, 2])を避けるために、必ず比較関数を渡す。

価格や年齢など「数値のキー」で並べる

const products = [
  { name: "Pen", price: 120 },
  { name: "Note", price: 300 },
  { name: "Bag", price: 450 },
];

// 価格の昇順
products.sort((a, b) => a.price - b.price);
console.log(products.map(p => p.name)); // ["Pen", "Note", "Bag"]

// 価格の降順
products.sort((a, b) => b.price - a.price);
console.log(products.map(p => p.name)); // ["Bag", "Note", "Pen"]
JavaScript
  • ポイント: 比較する「数値キー」を明示する。

複合条件(まず数値、同値なら文字列)

const items = [
  { name: "Banana", qty: 2 },
  { name: "Apple", qty: 2 },
  { name: "Orange", qty: 5 },
];

// qtyの昇順、qtyが同じなら名前の辞書順
items.sort((a, b) => {
  const d = a.qty - b.qty;
  return d !== 0 ? d : a.name.localeCompare(b.name);
});
console.log(items.map(i => `${i.qty}-${i.name}`)); // ["2-Apple","2-Banana","5-Orange"]
JavaScript
  • ポイント: 返り値を段階的に決める。文字列比較にはlocaleCompareが便利。

未定義・空値を末尾に送る(安全な比較)

const nums = [10, undefined, 3, null, 7];

nums.sort((a, b) => {
  const ax = Number.isFinite(a) ? a : Infinity; // 非数値は末尾へ
  const bx = Number.isFinite(b) ? b : Infinity;
  return ax - bx;
});

console.log(nums); // [3, 7, 10, undefined, null]
JavaScript
  • ポイント: 異常値の扱いを先に決めておくとバグを防げる。

よくある落とし穴と対策

  • 文字列として並ぶ問題: 比較関数を渡さないと文字列比較になる。数値は必ず (a, b) => a - b を使う。
  • 元配列が書き換わる: sortは破壊的。元を保持したいならスプレッドでコピーしてからsort。
  • NaNや非数値の混在: 比較で想定外の順序に。事前にフィルタするか、比較関数で扱いを定義。
  • 多言語文字列の並び: 文字列キーでソートする場合は localeCompare を使うと直感的な辞書順になりやすい。

目的別の使い分け

  • 単純な数値昇順/降順: (a, b) => a - b / (a, b) => b - a
  • 数値キー(price、ageなど): (a, b) => a.key - b.key
  • 複合条件(数値→文字列): 先に数値比較、同値なら localeCompare
  • 元を保持: const sorted = [...arr].sort(...)

練習問題(手を動かして覚える)

1. 数値配列を昇順に

const nums = [9, 1, 4, 1, 5];
console.log([...nums].sort((a, b) => a - b)); // [1, 1, 4, 5, 9]
JavaScript

2. 年齢の降順でユーザーを並べ替え

const users = [
  { name: "Aki", age: 19 },
  { name: "Mao", age: 22 },
  { name: "Ren", age: 17 },
];
console.log([...users].sort((a, b) => b.age - a.age).map(u => u.name)); // ["Mao","Aki","Ren"]
JavaScript

3. 点数の昇順、同点は名前の辞書順

const scores = [
  { name: "Banana", score: 80 },
  { name: "Apple", score: 80 },
  { name: "Orange", score: 90 },
];
const sorted = [...scores].sort((a, b) => {
  const d = a.score - b.score;
  return d !== 0 ? d : a.name.localeCompare(b.name);
});
console.log(sorted.map(s => `${s.score}-${s.name}`)); // ["80-Apple","80-Banana","90-Orange"]
JavaScript

直感的な指針

  • 数値なら必ず比較関数を渡す。
  • 元を壊したくないならコピーしてからsort。
  • 複合条件は「優先キー→次キー」の順で返り値を決める。
タイトルとURLをコピーしました