JavaScript 配列メソッド練習問題10選【map・filter・reduce実践ドリル】


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なし

次のステップ

配列メソッドを使いこなせるようになったら、以下の記事で次のレベルに進みましょう。