JavaScript配列のソート - sort()メソッドの基本的な使い方
JavaScriptのsort()メソッドを初心者向けに詳しく解説。基本的な使い方から数値・文字列・オブジェクトの並び替えまで、実践的なソート処理を豊富なサンプルコードとともに分かりやすく紹介します。
JavaScript配列のソート - sort()メソッドの基本的な使い方
みなさん、配列の要素を並び替えたいと思ったことはありませんか?
「ランキングを作りたいけど、どうやって数値を並べ替える?」 「商品を価格順に表示したいけど、複雑な並び替えってできるの?」
こんな疑問を持った方、多いですよね。
この記事では、JavaScript初心者向けにsort()メソッドの基本から実践まで分かりやすく解説します。 データの並び替えをマスターして、見やすく使いやすいプログラムを作れるようになりましょう。
それでは、一緒に配列のソートを学んでいきましょう!
sort()メソッドとは?
基本的な概念
sort()メソッドは、配列の要素を並び替えるJavaScriptの便利な機能です。 簡単に言うと、バラバラになった要素をきれいに順番に整理してくれます。
// 基本的な使い方let fruits = ["バナナ", "りんご", "オレンジ", "いちご"];console.log("ソート前:", fruits);
fruits.sort();console.log("ソート後:", fruits); // ["いちご", "オレンジ", "バナナ", "りんご"]
このように、とても簡単に文字列を並び替えることができます。
sort()メソッドの特徴
sort()メソッドの大切なポイントをお伝えします。
- 元の配列を変更:新しい配列は作らず、元の配列自体が変わります
- 文字列として比較:何も指定しないと文字として比較されます
- 比較関数を指定可能:自分で並び替えルールを決められます
- 安定ソート:同じ値の順序を保ちます
// 元の配列が変更される例let numbers = [3, 1, 4, 1, 5];let originalArray = numbers;
let sortedArray = numbers.sort();
console.log("numbers:", numbers); // [1, 1, 3, 4, 5]console.log("sortedArray:", sortedArray); // [1, 1, 3, 4, 5]console.log("同じ配列?", numbers === sortedArray); // trueconsole.log("元の配列と同じ?", numbers === originalArray); // true
sort()メソッドは元の配列を変更することを覚えておきましょう。
基本的な文字列ソート
アルファベットの並び替え
最も基本的な使い方から見てみましょう。
// アルファベットの並び替えlet letters = ["d", "b", "a", "c", "e"];console.log("ソート前:", letters);
letters.sort();console.log("ソート後:", letters); // ["a", "b", "c", "d", "e"]
アルファベットは自動的にa、b、c順に並びます。
// 大文字と小文字の混在let mixedCase = ["Banana", "apple", "Cherry", "date"];mixedCase.sort();console.log("大文字小文字混在:", mixedCase); // ["Banana", "Cherry", "apple", "date"]// 注意:大文字が小文字より前に来る
大文字と小文字が混在している場合、大文字の方が先に並びます。
日本語の並び替え
日本語でも同じように並び替えできます。
// ひらがなの並び替えlet hiragana = ["け", "あ", "そ", "う", "か"];hiragana.sort();console.log("ひらがな:", hiragana); // ["あ", "う", "か", "け", "そ"]
// カタカナの並び替えlet katakana = ["ケ", "ア", "ソ", "ウ", "カ"];katakana.sort();console.log("カタカナ:", katakana); // ["ア", "ウ", "カ", "ケ", "ソ"]
// 漢字を含む名前の並び替えlet names = ["田中", "佐藤", "鈴木", "高橋", "渡辺"];names.sort();console.log("名前:", names); // 文字コード順で並び替え
日本語も問題なく並び替えることができますね。
文字列の長さによる影響
文字列の長さが違う場合の動作を確認してみましょう。
// 文字列の長さが異なる場合let words = ["プログラミング", "JavaScript", "学習", "開発", "コード"];words.sort();console.log("単語:", words);
// 数字を含む文字列(注意が必要)let items = ["item1", "item10", "item2", "item20", "item3"];items.sort();console.log("項目:", items); // ["item1", "item10", "item2", "item20", "item3"]// 注意:"10"は"2"より前に来る(文字列として比較されるため)
この最後の例は重要です。 「10」が「2」より前に来てしまうんです。
数値の並び替え
デフォルトソートの問題
数値のソートには注意が必要です。
// 問題のある例:数値が文字列として扱われるlet numbers = [10, 2, 30, 4, 1];numbers.sort();console.log("デフォルトソート:", numbers); // [1, 10, 2, 30, 4]// 期待した結果ではない!
これは「1、10、2、30、4」という順番になってしまいます。 数値としては間違った並び順ですよね。
数値用の比較関数
正しく数値を並び替えるには、比較関数を使います。
// 昇順(小さい順)のソートlet numbers1 = [10, 2, 30, 4, 1];numbers1.sort(function(a, b) { return a - b;});console.log("昇順:", numbers1); // [1, 2, 4, 10, 30]
このa - b
という式がポイントです。
これで正しく数値として比較されます。
// 降順(大きい順)のソートlet numbers2 = [10, 2, 30, 4, 1];numbers2.sort(function(a, b) { return b - a;});console.log("降順:", numbers2); // [30, 10, 4, 2, 1]
b - a
にすると大きい順になります。
// アロー関数を使った簡潔な書き方let numbers3 = [15, 3, 8, 12, 6];let ascending = [...numbers3].sort((a, b) => a - b);let descending = [...numbers3].sort((a, b) => b - a);
console.log("元の配列:", numbers3); // [15, 3, 8, 12, 6]console.log("昇順コピー:", ascending); // [3, 6, 8, 12, 15]console.log("降順コピー:", descending); // [15, 12, 8, 6, 3]
[...numbers3]
の部分で配列のコピーを作っています。
これで元の配列は変更されません。
小数点を含む数値
小数点がある数値も同じ方法で並び替えできます。
// 小数点を含む数値のソートlet decimals = [3.14, 2.71, 1.41, 0.57, 4.20];
// 昇順let ascendingDecimals = [...decimals].sort((a, b) => a - b);console.log("小数点昇順:", ascendingDecimals); // [0.57, 1.41, 2.71, 3.14, 4.20]
// 降順let descendingDecimals = [...decimals].sort((a, b) => b - a);console.log("小数点降順:", descendingDecimals); // [4.20, 3.14, 2.71, 1.41, 0.57]
マイナスの数値や絶対値での並び替えもできます。
// 絶対値でのソートlet mixedNumbers = [-5, 3, -2, 8, -1, 6];let absoluteSort = [...mixedNumbers].sort((a, b) => Math.abs(a) - Math.abs(b));console.log("絶対値順:", absoluteSort); // [-1, -2, 3, -5, 6, 8]
絶対値で比較するにはMath.abs()
を使います。
オブジェクトの並び替え
基本的なオブジェクトソート
配列の中にオブジェクトが入っている場合の並び替えを見てみましょう。
// 学生のデータlet students = [ { name: "田中太郎", age: 20, score: 85 }, { name: "佐藤花子", age: 19, score: 92 }, { name: "鈴木次郎", age: 21, score: 78 }, { name: "高橋美咲", age: 18, score: 95 }];
この学生データを年齢順に並べてみます。
// 年齢順(昇順)let sortedByAge = [...students].sort((a, b) => a.age - b.age);console.log("年齢順:");sortedByAge.forEach(student => { console.log(`${student.name} (${student.age}歳): ${student.score}点`);});
a.age - b.age
で年齢を比較しています。
// スコア順(降順)let sortedByScore = [...students].sort((a, b) => b.score - a.score);console.log("スコア順:");sortedByScore.forEach(student => { console.log(`${student.name}: ${student.score}点 (${student.age}歳)`);});
高得点から順番に並びます。
// 名前順(文字列)let sortedByName = [...students].sort((a, b) => a.name.localeCompare(b.name));console.log("名前順:");sortedByName.forEach(student => { console.log(`${student.name} (${student.age}歳): ${student.score}点`);});
文字列の比較にはlocaleCompare()
を使うときれいに並びます。
複数条件でのソート
複数の条件を組み合わせて並び替えることもできます。
// 商品データlet products = [ { name: "ノートPC", category: "電子機器", price: 89800 }, { name: "マウス", category: "電子機器", price: 2980 }, { name: "本", category: "書籍", price: 1500 }, { name: "雑誌", category: "書籍", price: 800 }, { name: "キーボード", category: "電子機器", price: 5980 }, { name: "辞書", category: "書籍", price: 3000 }];
// カテゴリー順、同じカテゴリー内では価格順(昇順)let sortedProducts = [...products].sort((a, b) => { // まずカテゴリーで比較 if (a.category !== b.category) { return a.category.localeCompare(b.category); } // カテゴリーが同じ場合は価格で比較 return a.price - b.price;});
console.log("カテゴリー別、価格順:");sortedProducts.forEach(product => { console.log(`[${product.category}] ${product.name}: ¥${product.price}`);});
まずカテゴリーで分類して、同じカテゴリー内では価格順に並べています。
日付による並び替え
日付での並び替えも見てみましょう。
// イベントデータlet events = [ { title: "会議A", date: new Date("2025-01-15") }, { title: "プレゼン", date: new Date("2025-01-10") }, { title: "会議B", date: new Date("2025-01-20") }, { title: "研修", date: new Date("2025-01-08") }];
// 日付順(古い順)let sortedByDate = [...events].sort((a, b) => a.date - b.date);console.log("日付順(古い順):");sortedByDate.forEach(event => { console.log(`${event.title}: ${event.date.toLocaleDateString("ja-JP")}`);});
日付オブジェクトも数値と同じように比較できます。
よくある間違いとその対策
元の配列を変更したくない場合
「元の配列はそのまま残しておきたい」という場合の対策方法です。
// 問題のある例:元の配列が変更されるlet originalNumbers = [3, 1, 4, 1, 5];let sortedNumbers = originalNumbers.sort((a, b) => a - b);
console.log("元の配列:", originalNumbers); // [1, 1, 3, 4, 5](変更されている)console.log("ソート済み:", sortedNumbers); // [1, 1, 3, 4, 5]
これでは元の配列も変わってしまいます。
// 解決方法1: スプレッド演算子でコピーlet originalNumbers2 = [3, 1, 4, 1, 5];let sortedNumbers2 = [...originalNumbers2].sort((a, b) => a - b);
console.log("元の配列:", originalNumbers2); // [3, 1, 4, 1, 5](変更されない)console.log("ソート済み:", sortedNumbers2); // [1, 1, 3, 4, 5]
[...originalNumbers2]
でコピーを作ってからソートしています。
// 解決方法2: Array.from()を使用let originalNumbers3 = [3, 1, 4, 1, 5];let sortedNumbers3 = Array.from(originalNumbers3).sort((a, b) => a - b);
// 解決方法3: slice()を使用let originalNumbers4 = [3, 1, 4, 1, 5];let sortedNumbers4 = originalNumbers4.slice().sort((a, b) => a - b);
どの方法でも元の配列を保護できます。
数値の文字列化による問題
数値と文字列が混在している場合の対処法です。
// 問題のある例let mixedData = [1, 10, 2, "3", "20"];mixedData.sort();console.log("問題のあるソート:", mixedData); // [1, 10, 2, "20", "3"]
これでは正しい順番になりません。
// 解決方法:数値に変換してからソートlet mixedData2 = [1, 10, 2, "3", "20"];let numberSorted = mixedData2.map(item => Number(item)).sort((a, b) => a - b);console.log("数値として正しくソート:", numberSorted); // [1, 2, 3, 10, 20]
Number()
で数値に変換してからソートします。
// より安全な方法:型チェック付きfunction safeNumericSort(array) { return array .filter(item => !isNaN(Number(item))) // 数値に変換可能なもののみ .map(item => Number(item)) .sort((a, b) => a - b);}
let mixedData3 = [1, 10, 2, "3", "abc", "20", null];console.log("安全なソート:", safeNumericSort(mixedData3)); // [1, 2, 3, 10, 20]
数値に変換できないものは除外してからソートしています。
日本語の適切なソート
日本語の並び替えをもっと正確にする方法です。
// 問題のある例:文字コード順でのソートlet japaneseNames = ["田中", "あいう", "アイウ", "佐藤", "かきく", "カキク"];japaneseNames.sort();console.log("文字コード順:", japaneseNames);
これだと思った通りの順番にならないことがあります。
// 解決方法:localeCompare()の使用let japaneseNames2 = ["田中", "あいう", "アイウ", "佐藤", "かきく", "カキク"];japaneseNames2.sort((a, b) => a.localeCompare(b, 'ja'));console.log("日本語適切順:", japaneseNames2);
localeCompare()
を使うとより自然な順序になります。
// より詳細な設定let japaneseNames3 = ["田中", "あいう", "アイウ", "佐藤", "かきく", "カキク"];japaneseNames3.sort((a, b) => a.localeCompare(b, 'ja', { sensitivity: 'base', // ひらがな・カタカナを同じものとして扱う numeric: true // 数値として解釈}));console.log("詳細設定ソート:", japaneseNames3);
細かい設定で、より思った通りの並び順にできます。
まとめ
JavaScript のsort()メソッドについて、基本から応用まで詳しく学習しました。
基本的な特徴:
- 配列の要素を並び替える組み込みメソッド
- 元の配列を変更し、ソートされた配列を返す
- デフォルトでは文字列として比較
- 比較関数でカスタムソートが可能
重要なポイント:
- 数値ソートには比較関数
(a, b) => a - b
が必須 - 元の配列を保持したい場合はコピーを作成
- オブジェクトの複数条件ソートも実装可能
- 日本語ソートには
localeCompare()
を使用
実践的な応用例:
- 学生の成績順並び替え
- 商品の価格順・カテゴリー別表示
- イベントの日付順管理
- 複合条件での高度なソート処理
注意すべき点:
- 元の配列が変更される副作用
- 数値の文字列化による予期しない結果
- 日本語の適切なソート方法
sort()メソッドは、データの整理と表示において非常に重要な機能です。 適切に理解して使用することで、ユーザーにとって見やすく使いやすいアプリケーションを作成できます。
今回学んだ内容を実際のプロジェクトで活用してみませんか? データの並び替えをマスターすることで、より実用的なWebアプリケーションを開発できるようになりますよ!