JavaScriptの配列は主流言語の中で最も豊富なメソッドAPIの一つを持っています。しかしほとんどのチュートリアルはmapとfilterを不自然な例で教えます。配列の数値を2倍にする、偶数を絞り込むなど。そして残りは自分で理解するよう放置します。実際の本番コードで登場するメソッドを、現実的なデータを使って見ていきましょう:製品、注文、ユーザーレコードです。
使用するデータセット
例を具体的に保つため、この記事全体を通じてリアルな製品カタログを使います:
const products = [
{ id: 1, name: 'Wireless Keyboard', category: 'electronics', price: 79.99, rating: 4.5, inStock: true },
{ id: 2, name: 'Mechanical Keyboard', category: 'electronics', price: 149.99, rating: 4.8, inStock: true },
{ id: 3, name: 'USB-C Hub', category: 'electronics', price: 49.99, rating: 4.2, inStock: false },
{ id: 4, name: 'Standing Desk', category: 'furniture', price: 499.99, rating: 4.6, inStock: true },
{ id: 5, name: 'Desk Lamp', category: 'furniture', price: 39.99, rating: 4.1, inStock: true },
{ id: 6, name: 'Monitor Arm', category: 'electronics', price: 89.99, rating: 4.7, inStock: false },
];map() — すべての要素を変換する
Array.prototype.map()は各要素に関数を適用して新しい配列を作成します。データ変換の主力です。APIレスポンスをUIが必要とする形式に整形します:
// Extract just the display data for a product list component
const productCards = products.map(product => ({
id: product.id,
name: product.name,
price: `$${product.price.toFixed(2)}`,
badge: product.inStock ? 'In Stock' : 'Out of Stock',
stars: '★'.repeat(Math.round(product.rating))
}));
// productCards[0] → { id: 1, name: 'Wireless Keyboard', price: '$79.99', badge: 'In Stock', stars: '★★★★★' }
// Apply a discount to all prices
const discounted = products.map(p => ({
...p,
price: parseFloat((p.price * 0.9).toFixed(2)),
originalPrice: p.price
}));map()は元の配列を決して変更しません。常に新しい配列を返します。そのためチェーンしても安全で、変換が目的の場合はforループより好ましいです。
filter() — サブセットを取得する
filter()はコールバックがtrueを返す要素のみを含む新しい配列を返します:
const inStockProducts = products.filter(p => p.inStock);
const electronicsOnly = products.filter(p => p.category === 'electronics');
const affordableInStock = products.filter(p => p.inStock && p.price < 100);
// Chain map + filter to get display-ready affordable in-stock electronics
const featuredItems = products
.filter(p => p.inStock && p.rating >= 4.5)
.map(p => ({ id: p.id, name: p.name, price: `$${p.price}` }));reduce() — 万能ナイフ
Array.prototype.reduce()は、シグネチャが難しそうに見えるため開発者が避けがちなメソッドです。しかし一度理解すると常に使うようになります。配列を単一の値に「縮小」します。その値は何でも構いません:数値、オブジェクト、別の配列。現実的な使用例として、配列から検索マップを構築してみましょう:
// Group products by category (the pattern that makes reduce click)
const byCategory = products.reduce((acc, product) => {
const cat = product.category;
if (!acc[cat]) acc[cat] = [];
acc[cat].push(product);
return acc;
}, {}); // starting value is an empty object
// byCategory.electronics → [Wireless Keyboard, Mechanical Keyboard, USB-C Hub, Monitor Arm]
// byCategory.furniture → [Standing Desk, Desk Lamp]
// Build an id → product lookup (O(1) access instead of .find() on every render)
const productById = products.reduce((acc, p) => {
acc[p.id] = p;
return acc;
}, {});
const keyboard = productById[2]; // instant lookup
// Calculate total cart value
const cart = [{ productId: 1, qty: 2 }, { productId: 4, qty: 1 }];
const cartTotal = cart.reduce((total, item) => {
const product = productById[item.productId];
return total + (product.price * item.qty);
}, 0);
// 79.99 * 2 + 499.99 * 1 = 659.97reduce()を使っている場合、よりシンプルな代替を検討してください。products.reduce((sum, p) => sum + p.price, 0)は単純なケースに十分です。しかしグルーピングやインデックス作成ではreduce()は無敵です。find()とfindIndex() — 最初の一致で停止する
一つの要素だけ必要な時にfilter()を使うのはよくある間違いです。filter()は常に配列全体をスキャンします。find()は一致が見つかるとすぐに停止します。最良ケースO(1)対filterのO(n)です:
// ❌ Returns an array, scans everything even after finding a match
const found = products.filter(p => p.id === 3)[0];
// ✅ Returns the item directly, stops at first match
const product = products.find(p => p.id === 3);
// { id: 3, name: 'USB-C Hub', ... }
// findIndex() — gives you the position (useful for updates and deletions)
const idx = products.findIndex(p => p.id === 3);
// Update immutably:
const updated = [
...products.slice(0, idx),
{ ...products[idx], inStock: true },
...products.slice(idx + 1)
];some()とevery() — 真偽値チェック
配列の内容についてはい/いいえの答えが必要な時、some()とevery()はフィルタリングして長さを確認するより簡潔です:
const hasOutOfStock = products.some(p => !p.inStock); // true
const allHighRated = products.every(p => p.rating >= 4.0); // true
const allInStock = products.every(p => p.inStock); // false
// Common pattern: form validation
const formFields = [
{ name: 'email', value: '[email protected]', valid: true },
{ name: 'password', value: '', valid: false },
{ name: 'username', value: 'dev123', valid: true }
];
const isFormValid = formFields.every(field => field.valid); // false
const hasAnyError = formFields.some(field => !field.valid); // trueflat()とflatMap() — ネストした配列の処理
APIがネストした配列を返す場合、flat()とflatMap()でフラットにできます。flatMap()はmap操作が入力ごとに0個、1個、または複数の要素を生成する可能性がある場合に特に便利です:
// flat() — collapse one level of nesting
const orderLines = [
['Wireless Keyboard', 'USB-C Hub'],
['Standing Desk'],
['Mechanical Keyboard', 'Monitor Arm', 'Desk Lamp']
];
const allItems = orderLines.flat();
// ['Wireless Keyboard', 'USB-C Hub', 'Standing Desk', 'Mechanical Keyboard', ...]
// flatMap() — map + flat in one pass (more efficient than chaining)
const ordersWithTags = [
{ id: 101, items: ['keyboard', 'hub'], tags: ['electronics'] },
{ id: 102, items: ['desk', 'lamp'], tags: ['furniture', 'sale'] },
];
// Get all unique tags across all orders
const allTags = ordersWithTags.flatMap(order => order.tags);
// ['electronics', 'furniture', 'sale']
// Filter-and-extract in one pass with flatMap
const expensiveNames = products.flatMap(p =>
p.price > 100 ? [p.name] : [] // return empty array to skip, or [value] to include
);
// ['Mechanical Keyboard', 'Standing Desk']Array.from() — 配列的なものを変換する
Array.from()は反復可能なものを本当の配列に変換します。DOM NodeList、Set、Map、ジェネレーターの結果などで常に必要になります:
// Convert a NodeList to an array so you can use .map() and .filter()
const checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]'));
const checkedValues = checkboxes
.filter(el => el.checked)
.map(el => el.value);
// Deduplicate an array using Set → Array.from
const tags = ['electronics', 'sale', 'electronics', 'new', 'sale'];
const unique = Array.from(new Set(tags));
// ['electronics', 'sale', 'new']
// Create a range (like Python's range())
const range = Array.from({ length: 5 }, (_, i) => i + 1);
// [1, 2, 3, 4, 5]
// Extract Map entries for further processing
const priceMap = new Map(products.map(p => [p.id, p.price]));
const prices = Array.from(priceMap.values()); // [79.99, 149.99, ...]正しくソートする
デフォルトのsort()はすべてを文字列に変換するため、数値のソートが間違った結果になり、非ASCII文字の文字列ソートが壊れます。常にコンパレーターを渡してください:
// ❌ Default sort — wrong for numbers
[10, 9, 100, 2].sort(); // [10, 100, 2, 9] ← string order
// ✅ Numeric sort
[10, 9, 100, 2].sort((a, b) => a - b); // [2, 9, 10, 100] ascending
[10, 9, 100, 2].sort((a, b) => b - a); // [100, 10, 9, 2] descending
// Sort products by price ascending
const byPrice = [...products].sort((a, b) => a.price - b.price);
// Sort by name — use localeCompare for proper string ordering
const byName = [...products].sort((a, b) =>
a.name.localeCompare(b.name, 'en', { sensitivity: 'base' })
);
// Multi-key sort: category first, then rating descending
const sorted = [...products].sort((a, b) => {
if (a.category !== b.category) return a.category.localeCompare(b.category);
return b.rating - a.rating;
});sort()は元の配列を変更します。元の順序を保持したい場合は必ずスプレッドを先に使ってください([...products].sort(...))。Object.groupBy() — ES2024のグルーピング
ES2024以前は配列をグループ化するためにreduce()を使っていました(前述の通り)。今はビルトインがあります:Object.groupBy()。単純なグループ化ケースにはよりシンプルです:
// Group products by category — ES2024
const grouped = Object.groupBy(products, p => p.category);
// {
// electronics: [Wireless Keyboard, Mechanical Keyboard, USB-C Hub, Monitor Arm],
// furniture: [Standing Desk, Desk Lamp]
// }
// Group by stock status
const byStock = Object.groupBy(products, p => p.inStock ? 'available' : 'unavailable');
// Group orders by month
const orders = [
{ id: 1, date: new Date('2026-01-15'), total: 129.99 },
{ id: 2, date: new Date('2026-01-22'), total: 49.99 },
{ id: 3, date: new Date('2026-02-05'), total: 89.99 },
];
const byMonth = Object.groupBy(orders, o =>
o.date.toLocaleString('en', { month: 'long', year: 'numeric' })
);Object.groupBy()はNode.js 21+と2024年半ば以降の全ての最新ブラウザで利用可能です。現在の互換性についてはMDNのgroupByリファレンスを確認してください。古い環境ではreduce()パターンが引き続き使えます。
便利なツール
APIからのJSON配列データを扱う際、これらのツールが時間を節約します:JSONフォーマッターで深くネストしたペイロードを確認し、JSONパスで大きな配列から特定のフィールドを検索し、JSフォーマッターでメソッドチェーンのコードを整形できます。完全なMDNの配列リファレンスはブックマークする価値があります。ほとんどの開発者が知っているよりも多くのメソッドがあります。
まとめ
JavaScriptの配列メソッドはユーティリティライブラリに頼りたくなることのほとんどをカバーしています。変換とサブセット取得にはmap()とfilter()、グループ化とインデックス作成にはreduce()、検索にはfilter()[0]よりfind()、1パスのフィルター・変換にはflatMap()、そして最新環境でのシンプルなグループ化にはObject.groupBy()。重要なのは仕事に適したツールを使うことです。ほとんどのループは適切なメソッドに置き換えられることを知っておきましょう。