JavaScript 配列メソッドを実践で身につけよう
JavaScriptの配列メソッド(map、filter、reduce、find、sortなど)は、実務で最も使用頻度が高い機能の一つです。この記事では、実践的な10問の練習問題を通じて、配列メソッドを確実に使いこなせるようになることを目指します。
各問題には「ヒント」と「解答例」を用意しています。まずは自力で考え、詰まったらヒントを参考にしてください。
対象レベル
- JavaScriptの基本文法(変数、関数、条件分岐、ループ)を理解している方
- 配列メソッドを「知っているけど使いこなせない」方
- 実務やポートフォリオで使えるスキルを身につけたい方
Q1. map:商品価格を税込みに変換する
以下の商品リストの価格を、すべて税込み(10%)に変換した新しい配列を作成してください。
const products = [
{ name: 'Tシャツ', price: 2000 },
{ name: 'パーカー', price: 5000 },
{ name: 'キャップ', price: 1500 },
{ name: 'スニーカー', price: 8000 }
];ヒント
map()は配列の各要素を変換して新しい配列を返します。スプレッド構文 {…item} を使えば元のオブジェクトを変更せずにコピーできます。
解答例
const taxIncluded = products.map(item => ({
...item,
price: item.price * 1.1
}));
console.log(taxIncluded);ポイント: map()はイミュータブル(元の配列を変更しない)な操作です。スプレッド構文で元のオブジェクトをコピーし、priceだけを上書きしています。
Q2. filter:条件に合う要素を抽出する
以下のユーザーリストから、20歳以上かつアクティブなユーザーだけを抽出してください。
const users = [
{ name: '田中', age: 25, active: true },
{ name: '佐藤', age: 17, active: true },
{ name: '鈴木', age: 30, active: false },
{ name: '高橋', age: 22, active: true },
{ name: '伊藤', age: 19, active: true }
];解答例
const activeAdults = users.filter(user => user.age >= 20 && user.active);
console.log(activeAdults);ポイント: user.active === trueと書かなくても、user.activeだけで真偽値の判定ができます。
Q3. find / findIndex:最初に一致する要素を見つける
以下の注文リストから、ステータスが「pending」の最初の注文とそのインデックス番号を取得してください。
const orders = [
{ id: 101, status: 'completed', total: 3000 },
{ id: 102, status: 'completed', total: 1500 },
{ id: 103, status: 'pending', total: 4200 },
{ id: 104, status: 'pending', total: 800 },
{ id: 105, status: 'cancelled', total: 2000 }
];解答例
const pendingOrder = orders.find(order => order.status === 'pending');
const pendingIndex = orders.findIndex(order => order.status === 'pending');
console.log(pendingOrder);
console.log(pendingIndex);ポイント: filter()は条件に合う全要素を配列で返しますが、find()は最初の1つだけを返します。1つだけ必要な場合はfind()の方が効率的です。
Q4. reduce:合計値を計算する
以下のカートの商品リストから、合計金額を計算してください。
const cart = [
{ name: 'ノートPC', price: 120000, quantity: 1 },
{ name: 'マウス', price: 3000, quantity: 2 },
{ name: 'キーボード', price: 8000, quantity: 1 },
{ name: 'モニター', price: 35000, quantity: 2 }
];解答例
const total = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
console.log(total);ポイント: reduce()の第2引数(初期値)に0を渡すのを忘れないようにしましょう。省略すると配列の最初の要素が初期値になり、オブジェクト配列では意図しない動作になります。
Q5. some / every:条件の判定
以下のパスワードリストに対して、8文字以上のパスワードが1つでもあるか、すべてのパスワードが8文字以上か、を判定してください。
const passwords = ['abc', 'password123', 'hello', 'securePass!', '12345678'];解答例
const hasLong = passwords.some(pw => pw.length >= 8);
const allLong = passwords.every(pw => pw.length >= 8);
console.log(hasLong, allLong);ポイント: バリデーション処理でよく使うパターンです。フォームの入力チェックで「いずれかが未入力か」をsome()で、「全て入力済みか」をevery()で判定できます。
Q6. sort:オブジェクト配列を並べ替える
以下の記事リストを、公開日が新しい順に並べ替えてください。
const articles = [
{ title: 'CSS Grid入門', publishedAt: '2025-01-15' },
{ title: 'React Hooks解説', publishedAt: '2025-03-20' },
{ title: 'JavaScript基礎', publishedAt: '2024-12-01' },
{ title: 'TypeScript実践', publishedAt: '2025-02-10' }
];解答例
const sorted = [...articles].sort((a, b) =>
b.publishedAt.localeCompare(a.publishedAt)
);
sorted.forEach(a => console.log(a.title));ポイント: sort()は破壊的メソッドなので、スプレッド構文でコピーしてからソートするのがベストプラクティスです。
Q7. map + filter:チェーンで組み合わせる
以下の生徒リストから、合格者(スコア60以上)の名前だけを抽出した配列を作成してください。
const students = [
{ name: '山田', score: 85 },
{ name: '中村', score: 42 },
{ name: '小林', score: 73 },
{ name: '加藤', score: 58 },
{ name: '吉田', score: 91 }
];解答例
const passedNames = students
.filter(s => s.score >= 60)
.map(s => s.name);
console.log(passedNames);ポイント: 先にfilter()で絞り込んでからmap()で変換する方が、処理する要素数が少なくなり効率的です。
Q8. reduce:グループ化する
以下の商品リストを、カテゴリごとにグループ化したオブジェクトに変換してください。
const items = [
{ name: 'りんご', category: 'fruit' },
{ name: 'キャベツ', category: 'vegetable' },
{ name: 'バナナ', category: 'fruit' },
{ name: 'にんじん', category: 'vegetable' },
{ name: 'ぶどう', category: 'fruit' }
];解答例
const grouped = items.reduce((acc, item) => ({
...acc,
[item.category]: [...(acc[item.category] || []), item.name]
}), {});
console.log(grouped);ポイント: reduce()でオブジェクトを構築するパターンは実務で頻出です。ES2024以降ではObject.groupBy()も使えます。
Q9. flatMap:ネストした配列を展開する
以下のユーザーリストから、全ユーザーのスキルを重複なしで1つの配列にまとめてください。
const developers = [
{ name: '田中', skills: ['HTML', 'CSS', 'JavaScript'] },
{ name: '佐藤', skills: ['JavaScript', 'React', 'TypeScript'] },
{ name: '鈴木', skills: ['CSS', 'React', 'Vue'] }
];解答例
const allSkills = [...new Set(developers.flatMap(dev => dev.skills))];
console.log(allSkills);ポイント: flatMap()は配列の配列を1段階フラットにしながら変換できます。Setは重複を自動排除します。
Q10. 総合問題:売上データの分析
以下の売上データから、カテゴリごとの売上合計、売上トップ3の商品名、全商品の平均単価を求めてください。
const sales = [
{ product: 'ノートPC', category: 'electronics', price: 120000, sold: 15 },
{ product: 'マウス', category: 'electronics', price: 3000, sold: 200 },
{ product: 'デスク', category: 'furniture', price: 45000, sold: 30 },
{ product: 'チェア', category: 'furniture', price: 35000, sold: 50 },
{ product: 'モニター', category: 'electronics', price: 40000, sold: 80 },
{ product: 'ライト', category: 'furniture', price: 8000, sold: 100 }
];解答例
const salesByCategory = sales.reduce((acc, item) => ({
...acc,
[item.category]: (acc[item.category] || 0) + item.price * item.sold
}), {});
const top3 = [...sales]
.sort((a, b) => (b.price * b.sold) - (a.price * a.sold))
.slice(0, 3)
.map(item => item.product);
const avgPrice = sales.reduce((sum, item) => sum + item.price, 0) / sales.length;
console.log(salesByCategory, top3, avgPrice);ポイント: 実務のデータ処理は複数のメソッドを組み合わせて解決します。ステップを分けて可読性を保つことが重要です。
配列メソッド早見表
| メソッド | 用途 | 戻り値 | 元配列の変更 |
|---|---|---|---|
| map() | 各要素を変換 | 新しい配列 | なし |
| filter() | 条件で絞り込み | 新しい配列 | なし |
| reduce() | 1つの値に集約 | 任意の値 | なし |
| find() | 最初の一致要素 | 要素 or undefined | なし |
| findIndex() | 最初の一致位置 | 数値 or -1 | なし |
| some() | 1つでも一致するか | true / false | なし |
| every() | すべて一致するか | true / false | なし |
| sort() | 並べ替え | 同じ配列 | あり |
| flatMap() | 変換+フラット化 | 新しい配列 | なし |
| forEach() | 副作用の実行 | undefined | なし |
次のステップ
配列メソッドを使いこなせるようになったら、以下の記事で次のレベルに進みましょう。
