JavaScript: JavaScriptの配列応用
最終更新:2026-10-13
前のレッスンでは基本的な配列操作を学びました。ここでは配列の「パワームーブ」— 高階メソッドでレベルアップしましょう。より少ないコードでより多くのことができ、モダンJavaScript開発では不可欠なスキルです。
1. map — 各要素を変換する
mapはすべての要素に関数を実行し、新しい配列を返します。元の配列は変更されません。組み立てラインのように考えましょう:各要素が入り、変換され、新しい製品の一部として出てきます。
<script>
let prices = [10, 20, 30];
let doubled = prices.map(p => p * 2); // [20, 40, 60]
</script>
コールバックは3つの引数を受け取ります:(要素, インデックス, 元の配列)。ほとんどの場合、最初の1つだけが必要です。
filterはテストに合格した要素を残し、新しい配列を返します。元の配列は変更されません。セキュリティチェックポイントのように、条件を満たすアイテムは通過し、残りはフィルターされます。
<script>
let scores = [45, 80, 92, 55, 78, 98];
let passed = scores.filter(s => s >= 60); // [80, 92, 78, 98]
</script>
コールバックがtrueを返す要素は残され、falseを返す要素は破棄されます。
2. reduce — 1つの値に蓄積する
reduceは配列を1つの値に「圧縮」します。最も一般的な用途は合計です:
<script>
let nums = [1, 2, 3, 4, 5];
let sum = nums.reduce((acc, cur) => acc + cur, 0); // 15
</script>
パラメータの意味:
acc(アキュムレータ):実行中の合計で、前の繰り返しから引き継がれるcur(カレント):現在の要素- 2番目の引数
0はアキュムレータの初期値
💪
reduceは最初は複雑に見えますが、本質はシンプルです。ステップバイステップで配列を1つの値に圧縮します。合計、最大値の検索、出現回数のカウント —reduceはすべて対応できます。
▶ サンプル:map、filter、reduceの組み合わせ
▶ 試してみよう3. findとfindIndex
何も見つからない場合、findはundefinedを返し、findIndexは-1を返します。
<script>
let users = [
{ name: '花子', age: 20 },
{ name: '太郎', age: 17 },
{ name: '一郎', age: 25 }
];
users.find(u => u.age > 22); // { name: '一郎', age: 25 }
users.findIndex(u => u.age < 18); // 1(太郎のインデックス)
</script>
4. sort — 要素を並べ替える
sortは配列をインプレースで整列します(元の配列を変更します!)。デフォルトでは文字列としてソートされるため、多くの初心者が引っかかります:
<script>
let nums = [10, 1, 21, 2];
nums.sort(); // [1, 10, 2, 21] ← 文字列ソート! "10" < "2"
// 正しい:数値ソートには比較関数が必要
nums.sort((a, b) => a - b); // [1, 2, 10, 21] ← 昇順
nums.sort((a, b) => b - a); // [21, 10, 2, 1] ← 降順
</script>
sortは元の配列を変更します!元の配列を保持するには、先にコピーしましょう:[...arr].sort(...)。
▶ サンプル:学生の点数ランキング
▶ 試してみよう5. someとevery
<script>
let scores = [60, 75, 82, 90];
scores.some(s => s >= 90); // true — 誰かが90点以上
scores.some(s => s === 100); // false — 満点の人はいない
scores.every(s => s >= 60); // true — 全員合格
</script>
💪
someは「誰かが...か?」と問い、everyは「全員が...か?」と問いかけます。一方は存在をチェックし、もう一方は完全性をチェックします。
6. スプレッド演算子(...)
スプレッド演算子...は配列を「展開」します。コピーと結合によく使われます:
<script>
let a = [1, 2, 3];
let b = [...a]; // コピー: [1, 2, 3](新しい配列、参照ではない)
let c = [...a, 4, 5]; // 結合: [1, 2, 3, 4, 5]
let d = [0, ...a, 4]; // 挿入: [0, 1, 2, 3, 4]
let x = [1, 2], y = [3, 4];
let z = [...x, ...y]; // [1, 2, 3, 4]
</script>
7. 分割代入
配列から値を抽出し、位置で変数に代入します:
<script>
let [a, b, c] = [1, 2, 3];
// a = 1, b = 2, c = 3
let [first, ...rest] = [1, 2, 3, 4, 5];
// first = 1, rest = [2, 3, 4, 5]
let [name, score] = ['花子', 95];
// name = '花子', score = 95
</script>
💪 分割代入はコードを簡潔にします。関数が複数の値を返す場合、配列にまとめて分割代入するのはよくあるパターンです。
8. メソッドチェーン
高階メソッドは新しい配列を返すため、次々にチェーンできます:
<script>
let result = students
.filter(s => s.score >= 60) // まず、合格した生徒をフィルター
.map(s => s.name) // 次に、名前を抽出
.sort(); // 最後に、ソート
</script>
▶ サンプル:チェーンでデータを処理
▶ 試してみよう▶ サンプル:スプレッド演算子と分割代入
▶ 試してみよう❓ よくある質問
mapは新しい配列を返し、forEachはundefinedを返します。結果が必要な場合はmapを使い、アクションを実行するだけの場合はforEachを使います。forEachの中で手動でpushしないでください — それはmapの仕事です。sortは元の配列を変更するのですか?sortはインプレース操作で、新しい配列を返すのではなく要素を再配置します。元の配列を保持するには、先にコピーしましょう:[...arr].sort(...)。reduceで初期値を省略できますか?📖 まとめ
mapは各要素を新しい配列に変換し、filterは一致する要素を残し、reduceは1つの値に蓄積するfindは最初の一致する要素を返し、findIndexは最初の一致するインデックスを返すsortはデフォルトでは文字列順 — 数値には常に比較関数を渡す:(a, b) => a - bsomeはいずれかの要素が一致するかをチェックし、everyはすべての要素が一致するかをチェックする- スプレッド演算子
...は配列をコピー・結合し、分割代入は要素を変数に抽出する - 高階メソッドは新しい配列を返し、チェーンして簡潔で読みやすいコードが書ける
📝 練習問題
- 配列
[3, 8, 12, 5, 9, 17, 4]が与えられたら、filterで7より大きい数値を残し、mapで2倍にして出力してください。 reduceを使って、配列['りんご', 'バナナ', 'りんご', 'さくらんぼ', 'バナナ', 'りんご']の各単語の出現回数をカウントしてください →{ りんご: 3, バナナ: 2, さくらんぼ: 1 }。- 学生の配列(
nameとscoreを持つ)が与えられたら、チェーンを使って:合格した生徒をフィルター → 点数で降順ソート → 名前を新しい配列に抽出してください。結果をページに表示してください。