{ }codelper

学ぶ › JavaScript

さらに先へ · 17

並べ替え(ソート)

小さい順、大きい順、自分で決めた基準で並べる。

並べ替え(ソート)は値を順番に並べることです。
下の例は数を小さい順・大きい順に並べ、単語を文字順と「短い順」に並べます。

const [line1, line2] = require("fs").readFileSync(0, "utf8").trim().split("\n");const nums = line1.trim().split(/\s+/).map(Number);const words = line2.trim().split(/\s+/);console.log([...nums].sort((a, b) => a - b).join(" "));console.log([...nums].sort((a, b) => b - a).join(" "));console.log([...words].sort().join(" "));const byLength = (a, b) => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0);console.log([...words].sort(byLength).join(" "));
stdin
10 9 1 25 3
pear fig banana kiwi apple
stdout
1 3 9 10 25
25 10 9 3 1
apple banana fig kiwi pear
fig kiwi pear apple banana

ポイント

  • 基本は、数なら大きさ順、文字列なら辞書順(文字コード順)です。
  • 新しいリストを返す並べ替えと、その場で変える並べ替えがあります。
    Python の sorted(nums) は新しいリスト、nums.sort() はその場です。
  • 基準の渡し方は二通りあります。
    キー関数は値ごとに比べるキーを示します(Python の key=lambda w: (len(w), w) は「長さ、同じなら文字順」)。
  • 比較関数は二つの値を受け取り、前が先なら負、同じなら 0、後ろが先なら正を返します。
  • 安定ソートは、基準が同じ値どうしの元の順番を保ちます。
    安定でない並べ替えでは、同じときの基準(長さが同じなら文字順)まで比較関数に書きます。

言語ごとの書き方

Pythonsorted(nums)(新しいリスト)、nums.sort()(その場)。
大きい順は reverse=True、基準は key=lambda w: (len(w), w)。
安定です
JavaScriptarr.sort((a, b) => a - b) — その場で。
比較関数がないと数も文字列として比べます。
複数の基準は a.length - b.length || ...。
ES2019 から安定
TypeScriptJavaScript と同じです
JavaArrays.sort、Collections.sort。
大きい順は Comparator.reverseOrder()、基準は Comparator.comparingInt(String::length).thenComparing(...)。
オブジェクト配列と Collections.sort は安定。
int[] は比較関数を受け付けません
C#Array.Sort・List.Sort(その場、安定の約束なし)、LINQ OrderBy(...).ThenBy(...)・OrderByDescending(安定)
C++std::sort(v.begin(), v.end())、大きい順は std::greater<int>()。
比較ラムダは「前が先か」を bool で返します。
安定が必要なら std::stable_sort
Cqsort(a, n, sizeof a[0], cmp) — cmp は二つのポインタを受け取り、負・0・正を返します。
安定の約束なし
Craykonリスト.並べ替え() は小さい順。
リスト.並べ替え(短い順) のように比較関数の名前を渡します。
安定です

よくある間違い

数を比較関数なしで sort() したJavaScript · TypeScript

console.log([10, 9, 1].sort());

→ [ 1, 10, 9 ] — 数を文字列に変えて比べます

数には必ず (a, b) => a - b を渡します。

nums = nums.sort() と書いたPython

nums = [3, 1, 2]
nums = nums.sort()
print(nums)

→ None — sort はその場で並べ替えて何も返しません

nums.sort() だけを書くか、nums = sorted(nums) にします。

int[] に比較関数を渡したJava

int[] a = {3, 1, 2};
Arrays.sort(a, Comparator.reverseOrder());

→ コンパイルエラー — int[] 用の sort は比較関数を受け付けません

例のように Integer[] に変えるか、小さい順に並べてから逆に読みます。

言語ごとの違い
C の qsort の比較関数を return a - b; と書くと、大きな負の数と大きな正の数の引き算(例:-2000000000 - 2000000000)で int があふれて符号が反転し、順番が狂います。
(a > b) - (a < b) のように比較で書きましょう。

練習問題