JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptでオブジェクト配列をループ処理して新しいオブジェクトを作成する方法

例えば、次のようなオブジェクトの配列があったとします。

const arr = [
  {
    "customer": "Customer 1",
    "project": "1"
  },
  {
    "customer": "Customer 2",
    "project": "2"
  },
  {
    "customer": "Customer 2",
    "project": "3"
  }
]

ここで求められているのは、このような配列を受け取り、新しい配列を返すJavaScript関数を作成することです。

新しい配列では、同じ値を持つ customer キー同士をマージする必要があります。期待される出力は次のようになります。

const output = [
  {
    "Customer 1": {
      "projects": "1"
    }
  },
  {
    "Customer 2": {
      "projects": [
        "2",
        "3"
      ]
    }
  }
]

実装コード

それでは、実際にコードを書いてみましょう。この処理では、forEach() を使って元の配列を走査しながら、既存の顧客と一致するものがあればプロジェクトを追加し、存在しなければ新しいエントリを作成します。

const arr = [
  {
    "customer": "Customer 1",
    "project": "1"
  },
  {
    "customer": "Customer 2",
    "project": "2"
  },
  {
    "customer": "Customer 2",
    "project": "3"
  }
]

const groupCustomer = data => {
  const res = [];
  data.forEach(el => {
    let customer = res.filter(custom => {
      return el.customer === custom.customer;
    })[0];
    if(customer){
      customer.projects.push(el.project);
    }else{
      res.push({ customer: el.customer, projects: [el.project] });
    };
  });
  return res;
};
console.log(groupCustomer(arr));

コードの解説

この関数の動作を簡単に整理すると、次のようになります。

1. 結果用の空配列を用意: 変数 res に、最終的に返すグループ化済みデータを蓄積していきます。

2. 各要素を走査: forEach() により、元の配列の各オブジェクトに対して処理を行います。

3. 既存顧客の検索: filter() を使い、すでに同じ顧客名が登録されているかどうかをチェックします。

4. 分岐処理: 同じ顧客が見つかった場合は、その顧客の projects 配列に新しいプロジェクトを追加します。見つからない場合は、新しい顧客オブジェクトを作成して res に追加します。

出力結果

コンソールに出力される結果は以下の通りです。同じ顧客のプロジェクトが正しくひとつの配列にまとめられていることが確認できます。

[
  { customer: 'Customer 1', projects: [ '1' ] },
  { customer: 'Customer 2', projects: [ '2', '3' ] }
]

補足:より効率的な代替手法

上記の方法は分かりやすい反面、要素ごとに filter() を呼び出すため、配列が大きくなると計算量が O(n²) となりパフォーマンスが低下します。大量のデータを扱う場合は、オブジェクトや Map をインデックスとして利用する方法がおすすめです。

const groupCustomerEfficient = data => {
  const map = new Map();
  data.forEach(el => {
    if(map.has(el.customer)){
      map.get(el.customer).projects.push(el.project);
    }else{
      map.set(el.customer, { customer: el.customer, projects: [el.project] });
    }
  });
  return [...map.values()];
};

console.log(groupCustomerEfficient(arr));

このアプローチなら、計算量を O(n) に抑えられるため、大規模なデータセットでも高速に動作します。

  1. JavaScriptでIDごとにオブジェクトの配列をグループ化する方法

    JavaScriptでオブジェクトの配列をidなどの特定のキーごとにグループ化したい場合、reduce()メソッドを使うと簡潔に実装できます。この記事では、どのプロパティにも対応できる汎用的なgroupBy関数を作成し、実際のサンプルコードとともにその仕組みを詳しく解説します。 reduce()によるグループ化の考え方 reduce()は、配列の各要素を順番に処理しながら、1つの累積値(ここではオブジェクト)を組み立てていくメソッドです。各要素からキーの値を取り出し、その値がまだ結果オブジェクトに存在しなければ新しい配列を作成して、そこへ要素を追加していくことでグループ化を実現します。 サ

  2. JavaScriptでオブジェクトを含む「配列の配列」をループ処理する方法

    JavaScriptでオブジェクトを含む多次元配列をループするには?JavaScriptでは、オブジェクトを含む配列の配列(入れ子構造の配列)をループ処理する際、forEach()メソッドをネストして使用し、さらにfor...inループで各オブジェクトのプロパティにアクセスするのが一般的な方法です。以下に、具体的な実装例を紹介します。コード例<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=device