JavaScriptのmap, filter, reduceを使ったデータ変換の完全ガイド

JavaScriptのデータ変換は、プログラミングにおいて重要なスキルです。データを適切に変換することで、アプリケーションの効率性や柔軟性が大幅に向上します。特に、配列操作においてmap, filter, reduceといった高階関数を使うことで、複雑なデータ処理を簡潔に記述できます。これらの関数を理解し使いこなすことは、JavaScriptプログラマーにとって必須のスキルとなります。本記事では、これらの関数の基本的な使い方から応用例までを詳しく解説し、実際のコード例を通してその活用方法を学びます。

目次

JavaScriptのデータ変換とは

JavaScriptのデータ変換とは、あるデータ形式から別の形式へとデータを変えるプロセスを指します。これにより、データの構造を変更し、必要な情報を抽出し、データを適切な形に整えることができます。データ変換は、Web開発やアプリケーション開発において非常に重要な役割を果たし、データの可読性や操作性を向上させるために頻繁に使用されます。

データ変換の重要性

データ変換は、以下の理由から重要です。

  • データの整形:データを目的に応じた形式に変換することで、必要な情報を簡単に取得できます。
  • 効率的なデータ操作:特定の形式に変換されたデータは、操作や分析が容易になります。
  • データの一貫性:データを一貫した形式に保つことで、バグを減らし、保守性を向上させます。

データ変換の例

例えば、APIから取得したデータがオブジェクトの配列として提供される場合、そのデータを整形し、特定のフィールドだけを抽出して新しい配列を作成することがよくあります。このような操作は、データ変換の一例です。

JavaScriptには、データ変換を効率的に行うための高階関数が用意されており、その代表的なものがmap, filter, reduceです。次のセクションでは、これらの関数について詳しく見ていきます。

map関数の基本

map関数は、配列内のすべての要素に対して指定した関数を適用し、その結果から新しい配列を生成するメソッドです。元の配列は変更せず、新しい配列が返されます。

map関数の使い方

map関数の基本的な構文は次のとおりです。

const newArray = array.map(callbackFunction);

ここで、callbackFunctionは配列の各要素に対して実行される関数であり、次の3つの引数を取ることができます。

  • currentValue: 現在の要素
  • index (オプション): 現在の要素のインデックス
  • array (オプション): 元の配列

例: 数値の配列を2倍にする

次に、数値の配列を2倍にする例を見てみましょう。

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

この例では、元の配列numbersの各要素に対して、2倍の値を計算し、新しい配列doubledに格納しています。

例: オブジェクトの配列から特定のプロパティを抽出する

次に、オブジェクトの配列から特定のプロパティを抽出する例を見てみましょう。

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 }
];

const names = users.map(user => user.name);
console.log(names); // ['Alice', 'Bob', 'Charlie']

この例では、各ユーザーオブジェクトのnameプロパティを抽出し、新しい配列namesに格納しています。

map関数を使うことで、配列の各要素に対する操作を簡潔に記述でき、データ変換を効率的に行うことができます。次のセクションでは、filter関数について詳しく見ていきます。

filter関数の基本

filter関数は、配列の各要素に対して指定した条件を適用し、その条件を満たす要素だけを含む新しい配列を生成するメソッドです。元の配列は変更されません。

filter関数の使い方

filter関数の基本的な構文は次のとおりです。

const newArray = array.filter(callbackFunction);

ここで、callbackFunctionは配列の各要素に対して実行される関数であり、次の3つの引数を取ることができます。

  • currentValue: 現在の要素
  • index (オプション): 現在の要素のインデックス
  • array (オプション): 元の配列

例: 偶数の抽出

次に、数値の配列から偶数だけを抽出する例を見てみましょう。

const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers); // [2, 4, 6]

この例では、元の配列numbersの各要素に対して、偶数かどうかをチェックし、新しい配列evenNumbersに偶数だけを格納しています。

例: 特定の条件に一致するオブジェクトの抽出

次に、オブジェクトの配列から特定の条件に一致するオブジェクトを抽出する例を見てみましょう。

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 }
];

const usersOver30 = users.filter(user => user.age > 30);
console.log(usersOver30); // [{ name: 'Charlie', age: 35 }]

この例では、各ユーザーオブジェクトのageプロパティが30より大きいかどうかをチェックし、その条件を満たすオブジェクトを新しい配列usersOver30に格納しています。

filter関数を使うことで、配列から特定の条件に一致する要素だけを簡潔に抽出することができます。次のセクションでは、reduce関数について詳しく見ていきます。

reduce関数の基本

reduce関数は、配列の各要素に対して指定した関数を実行し、最終的に単一の値を生成するメソッドです。累積結果を保持しながら配列を反復処理することで、集計や集約のような操作を行うことができます。

reduce関数の使い方

reduce関数の基本的な構文は次のとおりです。

const result = array.reduce(callbackFunction, initialValue);

ここで、callbackFunctionは次の4つの引数を取ることができます。

  • accumulator: 累積結果
  • currentValue: 現在の要素
  • index (オプション): 現在の要素のインデックス
  • array (オプション): 元の配列

initialValueは、accumulatorの初期値です。これが省略されると、最初の要素が初期値として使用されます。

例: 数値の合計

次に、数値の配列の合計を求める例を見てみましょう。

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 15

この例では、元の配列numbersの各要素を累積して加算し、最終的に合計値をsumとして取得しています。

例: オブジェクトのプロパティの合計

次に、オブジェクトの配列から特定のプロパティの合計を求める例を見てみましょう。

const items = [
  { name: 'Apple', price: 100 },
  { name: 'Banana', price: 150 },
  { name: 'Cherry', price: 200 }
];

const totalPrice = items.reduce((accumulator, item) => accumulator + item.price, 0);
console.log(totalPrice); // 450

この例では、各オブジェクトのpriceプロパティを累積して加算し、最終的に合計価格をtotalPriceとして取得しています。

例: 配列をオブジェクトに変換

次に、配列をオブジェクトに変換する例を見てみましょう。

const fruits = ['apple', 'banana', 'cherry'];
const fruitObject = fruits.reduce((accumulator, fruit) => {
  accumulator[fruit] = true;
  return accumulator;
}, {});
console.log(fruitObject); // { apple: true, banana: true, cherry: true }

この例では、元の配列fruitsをオブジェクトに変換し、各要素をキーとするオブジェクトfruitObjectを生成しています。

reduce関数を使うことで、配列から単一の値やオブジェクトを効率的に生成することができます。次のセクションでは、map関数の応用例について詳しく見ていきます。

map関数の応用例

map関数を基本的な使い方だけでなく、さまざまな応用例を通じて実践的に利用する方法を紹介します。これにより、複雑なデータ変換や加工が簡単に行えるようになります。

例1: 配列のオブジェクトを別の形式に変換

次に、配列内のオブジェクトを別の形式に変換する例を見てみましょう。例えば、ユーザー情報の配列から、各ユーザーのフルネームと年齢を含む新しい配列を作成します。

const users = [
  { firstName: 'John', lastName: 'Doe', age: 25 },
  { firstName: 'Jane', lastName: 'Smith', age: 30 },
  { firstName: 'Emily', lastName: 'Jones', age: 22 }
];

const userSummaries = users.map(user => ({
  fullName: `${user.firstName} ${user.lastName}`,
  age: user.age
}));
console.log(userSummaries);
// [
//   { fullName: 'John Doe', age: 25 },
//   { fullName: 'Jane Smith', age: 30 },
//   { fullName: 'Emily Jones', age: 22 }
// ]

この例では、元の配列usersの各オブジェクトを変換して、フルネームと年齢を含む新しいオブジェクトを生成しています。

例2: 数値の配列を文字列に変換

数値の配列を文字列に変換することで、表示やログ出力に役立てることができます。

const numbers = [1, 2, 3, 4, 5];
const stringNumbers = numbers.map(number => `Number: ${number}`);
console.log(stringNumbers);
// ['Number: 1', 'Number: 2', 'Number: 3', 'Number: 4', 'Number: 5']

この例では、各数値を文字列に変換し、結果として新しい文字列の配列を生成しています。

例3: データの正規化

データを正規化することで、一貫性のある形式に揃えることができます。例えば、ユーザー名の配列をすべて小文字に変換します。

const userNames = ['Alice', 'BOB', 'Charlie'];
const normalizedNames = userNames.map(name => name.toLowerCase());
console.log(normalizedNames); // ['alice', 'bob', 'charlie']

この例では、元の配列userNamesの各要素を小文字に変換して、新しい配列normalizedNamesを生成しています。

例4: 複数のプロパティを操作する

配列内のオブジェクトの複数のプロパティを操作して、新しいオブジェクトを生成します。

const products = [
  { name: 'Laptop', price: 1000, quantity: 2 },
  { name: 'Phone', price: 500, quantity: 5 },
  { name: 'Tablet', price: 300, quantity: 3 }
];

const productSummaries = products.map(product => ({
  name: product.name,
  totalPrice: product.price * product.quantity
}));
console.log(productSummaries);
// [
//   { name: 'Laptop', totalPrice: 2000 },
//   { name: 'Phone', totalPrice: 2500 },
//   { name: 'Tablet', totalPrice: 900 }
// ]

この例では、各商品の総価格を計算し、新しい配列productSummariesを生成しています。

map関数の応用例を通じて、データの変換や整形が効率的に行えることが理解できました。次のセクションでは、filter関数の応用例について詳しく見ていきます。

filter関数の応用例

filter関数を基本的な使い方だけでなく、さまざまな応用例を通じて実践的に利用する方法を紹介します。これにより、配列から必要な要素だけを抽出する方法が理解できます。

例1: 特定の条件を満たすオブジェクトの抽出

次に、オブジェクトの配列から特定の条件を満たすオブジェクトを抽出する例を見てみましょう。例えば、30歳以上のユーザーを抽出します。

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 }
];

const usersOver30 = users.filter(user => user.age >= 30);
console.log(usersOver30);
// [{ name: 'Bob', age: 30 }, { name: 'Charlie', age: 35 }]

この例では、元の配列usersの各オブジェクトのageプロパティが30以上のものだけを新しい配列usersOver30に格納しています。

例2: 配列から重複を排除

次に、配列から重複する要素を排除する例を見てみましょう。

const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = numbers.filter((number, index, array) => array.indexOf(number) === index);
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]

この例では、元の配列numbersの各要素が初めて出現するインデックスと一致する場合のみ新しい配列uniqueNumbersに格納しています。

例3: 条件に一致しない要素の除外

次に、特定の条件に一致しない要素を除外する例を見てみましょう。例えば、指定された価格以上の商品だけを抽出します。

const products = [
  { name: 'Laptop', price: 1000 },
  { name: 'Phone', price: 500 },
  { name: 'Tablet', price: 300 }
];

const expensiveProducts = products.filter(product => product.price >= 500);
console.log(expensiveProducts); // [{ name: 'Laptop', price: 1000 }, { name: 'Phone', price: 500 }]

この例では、元の配列productsの各オブジェクトのpriceプロパティが500以上のものだけを新しい配列expensiveProductsに格納しています。

例4: 空の値や無効な値の除外

次に、空の値や無効な値を配列から除外する例を見てみましょう。

const values = [0, 1, '', null, 'hello', undefined, 42];
const validValues = values.filter(value => value);
console.log(validValues); // [1, 'hello', 42]

この例では、元の配列valuesの各要素が真と評価される場合のみ新しい配列validValuesに格納しています。

filter関数の応用例を通じて、特定の条件に一致する要素を効率的に抽出する方法が理解できました。次のセクションでは、reduce関数の応用例について詳しく見ていきます。

reduce関数の応用例

reduce関数を基本的な使い方だけでなく、さまざまな応用例を通じて実践的に利用する方法を紹介します。これにより、複雑なデータ操作や集計処理が簡単に行えるようになります。

例1: 配列の平均値を求める

次に、数値の配列の平均値を求める例を見てみましょう。

const numbers = [1, 2, 3, 4, 5];
const average = numbers.reduce((accumulator, currentValue, index, array) => {
  accumulator += currentValue;
  if (index === array.length - 1) {
    return accumulator / array.length;
  }
  return accumulator;
}, 0);
console.log(average); // 3

この例では、元の配列numbersの各要素を累積して加算し、最後に配列の長さで割ることで平均値を計算しています。

例2: ネストされた配列の平坦化

次に、ネストされた配列を平坦化する例を見てみましょう。

const nestedArray = [[1, 2], [3, 4], [5, 6]];
const flatArray = nestedArray.reduce((accumulator, currentValue) => {
  return accumulator.concat(currentValue);
}, []);
console.log(flatArray); // [1, 2, 3, 4, 5, 6]

この例では、元のネストされた配列nestedArrayの各要素を累積して平坦化し、新しい配列flatArrayに格納しています。

例3: 配列内のオブジェクトのプロパティを集計

次に、配列内のオブジェクトの特定のプロパティを集計する例を見てみましょう。例えば、各商品の数量を合計します。

const products = [
  { name: 'Laptop', quantity: 2 },
  { name: 'Phone', quantity: 5 },
  { name: 'Tablet', quantity: 3 }
];

const totalQuantity = products.reduce((accumulator, product) => {
  return accumulator + product.quantity;
}, 0);
console.log(totalQuantity); // 10

この例では、元の配列productsの各オブジェクトのquantityプロパティを累積して加算し、最終的な合計数量をtotalQuantityとして取得しています。

例4: オブジェクトの配列をグループ化

次に、オブジェクトの配列を特定のプロパティでグループ化する例を見てみましょう。例えば、ユーザーを年齢別にグループ化します。

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 25 }
];

const groupedByAge = users.reduce((accumulator, user) => {
  if (!accumulator[user.age]) {
    accumulator[user.age] = [];
  }
  accumulator[user.age].push(user);
  return accumulator;
}, {});
console.log(groupedByAge);
// {
//   '25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
//   '30': [{ name: 'Bob', age: 30 }]
// }

この例では、元の配列usersの各オブジェクトをageプロパティでグループ化し、新しいオブジェクトgroupedByAgeに格納しています。

reduce関数の応用例を通じて、配列の複雑なデータ操作や集計が効率的に行えることが理解できました。次のセクションでは、mapとfilterの組み合わせについて詳しく見ていきます。

mapとfilterの組み合わせ

mapとfilterを組み合わせて使用することで、データ変換とフィルタリングを同時に行うことができます。これにより、より複雑なデータ操作を効率的に実行できます。

例1: 数値の配列を変換しつつ特定の条件を満たす要素を抽出

次に、数値の配列を2倍に変換し、その中から偶数だけを抽出する例を見てみましょう。

const numbers = [1, 2, 3, 4, 5];
const doubledEvenNumbers = numbers
  .map(number => number * 2)
  .filter(number => number % 2 === 0);
console.log(doubledEvenNumbers); // [4, 8, 10]

この例では、まず元の配列numbersの各要素を2倍に変換し、その後、偶数だけを抽出して新しい配列doubledEvenNumbersに格納しています。

例2: オブジェクトの配列を変換しつつ特定の条件を満たす要素を抽出

次に、ユーザー情報の配列から、名前を大文字に変換し、30歳以上のユーザーだけを抽出する例を見てみましょう。

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 }
];

const usersOver30WithUppercaseNames = users
  .map(user => ({ name: user.name.toUpperCase(), age: user.age }))
  .filter(user => user.age >= 30);
console.log(usersOver30WithUppercaseNames);
// [{ name: 'BOB', age: 30 }, { name: 'CHARLIE', age: 35 }]

この例では、元の配列usersの各オブジェクトのnameプロパティを大文字に変換し、その後、年齢が30歳以上のユーザーだけを抽出して新しい配列usersOver30WithUppercaseNamesに格納しています。

例3: ネストされた配列の変換とフィルタリング

次に、ネストされた配列を平坦化し、特定の条件を満たす要素を抽出する例を見てみましょう。

const nestedArray = [[1, 2], [3, 4], [5, 6]];
const flatEvenNumbers = nestedArray
  .flat()
  .filter(number => number % 2 === 0);
console.log(flatEvenNumbers); // [2, 4, 6]

この例では、まず元のネストされた配列nestedArrayを平坦化し、その後、偶数だけを抽出して新しい配列flatEvenNumbersに格納しています。

例4: 商品リストの価格を変換しつつ特定の条件を満たす商品を抽出

次に、商品のリストから、価格を20%増加させ、特定の価格以上の商品だけを抽出する例を見てみましょう。

const products = [
  { name: 'Laptop', price: 1000 },
  { name: 'Phone', price: 500 },
  { name: 'Tablet', price: 300 }
];

const expensiveProducts = products
  .map(product => ({ name: product.name, price: product.price * 1.2 }))
  .filter(product => product.price >= 600);
console.log(expensiveProducts); // [{ name: 'Laptop', price: 1200 }]

この例では、元の配列productsの各オブジェクトのpriceプロパティを20%増加させ、その後、価格が600以上の商品だけを抽出して新しい配列expensiveProductsに格納しています。

mapとfilterを組み合わせることで、複数のデータ操作を連続して行うことができ、コードの可読性と効率性が向上します。次のセクションでは、map, filter, reduceの組み合わせについて詳しく見ていきます。

map, filter, reduceの組み合わせ

map, filter, reduceを組み合わせて使用することで、データの変換、フィルタリング、集約を一度に行うことができます。これにより、複雑なデータ操作を効率的に実行でき、コードの簡潔性と可読性が向上します。

例1: 数値の配列を変換、フィルタリング、合計する

次に、数値の配列を2倍に変換し、その中から偶数だけを抽出して合計を求める例を見てみましょう。

const numbers = [1, 2, 3, 4, 5];
const sumOfDoubledEvenNumbers = numbers
  .map(number => number * 2)
  .filter(number => number % 2 === 0)
  .reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sumOfDoubledEvenNumbers); // 20

この例では、元の配列numbersの各要素を2倍に変換し、その後、偶数だけを抽出して、最終的にその合計を計算しています。

例2: オブジェクトの配列を変換、フィルタリング、プロパティを集計

次に、ユーザー情報の配列から、名前を大文字に変換し、30歳以上のユーザーだけを抽出して、年齢の合計を求める例を見てみましょう。

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 }
];

const totalAgeOfUsersOver30 = users
  .map(user => ({ name: user.name.toUpperCase(), age: user.age }))
  .filter(user => user.age >= 30)
  .reduce((accumulator, user) => accumulator + user.age, 0);
console.log(totalAgeOfUsersOver30); // 65

この例では、元の配列usersの各オブジェクトのnameプロパティを大文字に変換し、その後、30歳以上のユーザーだけを抽出して、最終的にその年齢の合計を計算しています。

例3: 商品リストの価格を変換、フィルタリング、総価格を計算

次に、商品のリストから、価格を20%増加させ、特定の価格以上の商品だけを抽出して、その総価格を計算する例を見てみましょう。

const products = [
  { name: 'Laptop', price: 1000 },
  { name: 'Phone', price: 500 },
  { name: 'Tablet', price: 300 }
];

const totalExpensiveProductPrice = products
  .map(product => ({ name: product.name, price: product.price * 1.2 }))
  .filter(product => product.price >= 600)
  .reduce((accumulator, product) => accumulator + product.price, 0);
console.log(totalExpensiveProductPrice); // 1200

この例では、元の配列productsの各オブジェクトのpriceプロパティを20%増加させ、その後、価格が600以上の商品だけを抽出して、最終的にその総価格を計算しています。

例4: 複雑なデータ構造を変換、フィルタリング、集計

次に、複雑なデータ構造の配列から、特定のプロパティを変換、フィルタリングし、集計する例を見てみましょう。例えば、売上データから、売上が1000以上のものだけを抽出して、総売上を計算します。

const sales = [
  { product: 'Laptop', unitsSold: 5, unitPrice: 1000 },
  { product: 'Phone', unitsSold: 10, unitPrice: 500 },
  { product: 'Tablet', unitsSold: 8, unitPrice: 300 }
];

const totalHighValueSales = sales
  .map(sale => ({ ...sale, totalSale: sale.unitsSold * sale.unitPrice }))
  .filter(sale => sale.totalSale >= 1000)
  .reduce((accumulator, sale) => accumulator + sale.totalSale, 0);
console.log(totalHighValueSales); // 7000

この例では、元の配列salesの各オブジェクトにtotalSaleプロパティを追加し、その後、総売上が1000以上のものだけを抽出して、最終的にその総売上を計算しています。

map, filter, reduceを組み合わせることで、複数のデータ操作を連続して行うことができ、コードの効率性と可読性が大幅に向上します。次のセクションでは、エラーハンドリングとデバッグについて詳しく見ていきます。

エラーハンドリングとデバッグ

データ変換を行う際には、エラーハンドリングとデバッグが重要です。これにより、コードの信頼性と保守性が向上し、予期しない問題に対処する準備が整います。

エラーハンドリング

エラーハンドリングは、予期しないエラーが発生した場合に備えてコードを保護するための方法です。map, filter, reduceの各関数内でエラーハンドリングを実装することができます。

例: try-catchを使用したエラーハンドリング

次に、try-catchを使用してエラーハンドリングを行う例を見てみましょう。

const data = [1, 2, 'three', 4, 5];

const safeProcessing = data.map(item => {
  try {
    if (typeof item !== 'number') {
      throw new Error('Invalid item type');
    }
    return item * 2;
  } catch (error) {
    console.error(`Error processing item: ${error.message}`);
    return null; // or any other default value
  }
});

console.log(safeProcessing); // [2, 4, null, 8, 10]

この例では、配列dataの各要素を2倍に変換しますが、要素が数値でない場合はエラーをキャッチしてログに記録し、nullを返します。

デバッグ

デバッグは、コードの問題を特定し修正するためのプロセスです。デバッグツールやログ出力を使用して、map, filter, reduceの処理を追跡できます。

例: console.logを使用したデバッグ

次に、console.logを使用してデバッグを行う例を見てみましょう。

const numbers = [1, 2, 3, 4, 5];

const processedNumbers = numbers
  .map(number => {
    console.log(`Mapping number: ${number}`);
    return number * 2;
  })
  .filter(number => {
    console.log(`Filtering number: ${number}`);
    return number % 2 === 0;
  })
  .reduce((accumulator, number) => {
    console.log(`Reducing number: ${number}`);
    return accumulator + number;
  }, 0);

console.log(`Final result: ${processedNumbers}`); // 20

この例では、各関数内でconsole.logを使用して処理の各ステップを出力し、データがどのように変換されているかを確認できます。

デバッグツールの活用

ブラウザのデベロッパーツールやNode.jsのデバッガーを使用して、ブレークポイントを設定し、ステップ実行することで、コードの実行フローを詳細に追跡できます。

例: ブラウザのデベロッパーツールを使用

  1. ブラウザのデベロッパーツールを開きます(通常はF12キー)。
  2. “Sources”タブでスクリプトを開き、ブレークポイントを設定します。
  3. ページをリロードし、ブレークポイントでコードの実行が停止したら、ステップ実行して変数の値や関数の挙動を確認します。

エラーハンドリングとデバッグの技術を駆使することで、データ変換処理の信頼性と保守性を向上させることができます。次のセクションでは、練習問題と解答例について詳しく見ていきます。

練習問題と解答例

ここでは、map, filter, reduceを使用した練習問題を通じて、これらの関数の理解を深めます。各問題には解答例も含まれているので、実際にコードを書いて確認してみてください。

練習問題1: 数値の配列を3倍に変換し、10以上の数値だけを抽出する

次の数値の配列を使用して、各要素を3倍に変換し、その中から10以上の数値だけを抽出するコードを書いてください。

const numbers = [2, 5, 8, 1, 4];

解答例1:

const numbers = [2, 5, 8, 1, 4];

const result = numbers
  .map(number => number * 3)
  .filter(number => number >= 10);

console.log(result); // [15, 24, 12]

練習問題2: オブジェクトの配列から特定の条件を満たすプロパティを集計する

次のユーザー情報の配列を使用して、30歳以上のユーザーの年齢の合計を求めるコードを書いてください。

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 32 },
  { name: 'Charlie', age: 28 },
  { name: 'David', age: 35 }
];

解答例2:

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 32 },
  { name: 'Charlie', age: 28 },
  { name: 'David', age: 35 }
];

const totalAge = users
  .filter(user => user.age >= 30)
  .reduce((accumulator, user) => accumulator + user.age, 0);

console.log(totalAge); // 67

練習問題3: ネストされた配列を平坦化し、ユニークな要素だけを抽出する

次のネストされた配列を使用して、平坦化し、ユニークな要素だけを含む配列を生成するコードを書いてください。

const nestedArray = [[1, 2, 2], [3, 4], [4, 5, 6]];

解答例3:

const nestedArray = [[1, 2, 2], [3, 4], [4, 5, 6]];

const flatUniqueArray = nestedArray
  .flat()
  .filter((item, index, array) => array.indexOf(item) === index);

console.log(flatUniqueArray); // [1, 2, 3, 4, 5, 6]

練習問題4: 商品リストから価格を20%増加させ、特定の価格以上の商品だけを抽出し、名前のリストを生成する

次の商品のリストを使用して、価格を20%増加させ、その後、600以上の商品だけを抽出し、その名前のリストを生成するコードを書いてください。

const products = [
  { name: 'Laptop', price: 1000 },
  { name: 'Phone', price: 500 },
  { name: 'Tablet', price: 300 }
];

解答例4:

const products = [
  { name: 'Laptop', price: 1000 },
  { name: 'Phone', price: 500 },
  { name: 'Tablet', price: 300 }
];

const result = products
  .map(product => ({ ...product, price: product.price * 1.2 }))
  .filter(product => product.price >= 600)
  .map(product => product.name);

console.log(result); // ['Laptop']

これらの練習問題を通じて、map, filter, reduceの組み合わせを実際に使ってみることで、理解を深めることができます。次のセクションでは、まとめとして本記事の内容を振り返ります。

まとめ

本記事では、JavaScriptのデータ変換において重要なmap, filter, reduce関数の基本的な使い方から応用例までを詳しく解説しました。これらの高階関数を使うことで、配列のデータ変換、フィルタリング、集約を効率的かつ簡潔に行うことができます。

まず、map関数を使用して配列の各要素を変換する方法を学び、次にfilter関数を使って特定の条件を満たす要素を抽出する方法を見ました。さらに、reduce関数を用いて配列を単一の値に集約する方法についても解説しました。

それぞれの関数の応用例を通じて、実際の開発における具体的な使用方法を確認しました。また、map, filter, reduceを組み合わせることで、複雑なデータ操作を効率的に実行する方法を紹介しました。さらに、エラーハンドリングとデバッグのテクニックも解説し、コードの信頼性と保守性を向上させる方法を学びました。

最後に、練習問題を通じて理解を深める機会を提供しました。これらの問題を実際に解くことで、map, filter, reduceの使い方を実践的に学ぶことができます。

JavaScriptのデータ変換スキルは、日常のプログラミング作業において非常に重要です。本記事を通じて、これらの高階関数を効果的に活用し、より効率的で保守性の高いコードを書くための基礎を築くことができました。今後も実際のプロジェクトで積極的に活用し、さらなるスキル向上を目指してください。

コメント

コメントする

目次