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

【JavaScript】unitプロパティが同じオブジェクトをグループ化してbrandを結合する方法

はじめに

JavaScriptで配列内のオブジェクトを特定のプロパティの値ごとにグループ化したいケースはよくあります。本記事では、unitプロパティが同じ値を持つオブジェクトを1つにまとめ、brandプロパティをカンマ区切りで結合する方法を解説します。

元データの例

まず、次のようなオブジェクトの配列を考えてみましょう。

const arr = [
    {unit: 35, brand: 'CENTURY'},
    {unit: 35, brand: 'BADGER'},
    {unit: 25, brand: 'CENTURY'},
    {unit: 15, brand: 'CENTURY'},
    {unit: 25, brand: 'XEGAR'}
];

この配列に対して、「unitプロパティの値が等しいオブジェクト同士を1つのオブジェクトにまとめ、それぞれのbrandの値を結合する」関数を作成します。

期待される出力は以下の通りです。

const output = [
    {unit: 35, brand: 'CENTURY, BADGER'},
    {unit: 25, brand: 'CENTURY, XEGAR'},
    {unit: 15, brand: 'CENTURY'}
];

実装のアプローチ

処理の流れは次のようになります。

  1. 配列全体をループで走査します。
  2. ヘルパー関数を使って、結果配列の中に同じunit値を持つオブジェクトがすでに存在するかを検索します。
  3. 存在する場合は、そのオブジェクトのbrand値に現在のbrand値を連結して追加します。
  4. 存在しない場合は、新しいオブジェクトとして結果配列にpushします。

サンプルコード

以下が実際のコードです。

const arr = [
    {unit: 35, brand: 'CENTURY'},
    {unit: 35, brand: 'BADGER'},
    {unit: 25, brand: 'CENTURY'},
    {unit: 15, brand: 'CENTURY'},
    {unit: 25, brand: 'XEGAR'}
];

// 指定したunit値を持つ要素のインデックスを返すヘルパー関数
const indexOf = function(unit){
    return this.findIndex(el => el.unit === unit)
};
Array.prototype.indexOf = indexOf;

// グループ化を行う関数
const groupArray = arr => {
    const res = [];
    for(let i = 0; i < arr.length; i++){
       // 同じunit値を持つ要素が結果配列にあるか確認
       const ind = res.indexOf(arr[i].unit);
       if(ind !== -1){
          // 存在する場合:brand値をカンマ区切りで連結
          res[ind].brand += `, ${arr[i].brand}`;
       }else{
          // 存在しない場合:新しいオブジェクトとして追加
          res.push(arr[i]);
       }
    };
    return res;
};
console.log(groupArray(arr));

実行結果

このコードをコンソールで実行すると、次のような出力が得られます。

[
    { unit: 35, brand: 'CENTURY, BADGER' },
    { unit: 25, brand: 'CENTURY, XEGAR' },
    { unit: 15, brand: 'CENTURY' }
]

補足:よりモダンな書き方(reduceを使う)

上記のコードではArray.prototype.indexOfを上書きしていますが、既存メソッドの変更は避けた方が安全です。代わりに、reduce()Mapオブジェクトを活用すると、よりシンプルかつ安全に実装できます。

const groupArray = arr => {
    const map = new Map();
    for(const {unit, brand} of arr){
       if(map.has(unit)){
          map.get(unit).brand += `, ${brand}`;
       }else{
          map.set(unit, {unit, brand});
       }
    }
    return [...map.values()];
};
console.log(groupArray(arr));

Mapを使うことで、キーの検索が高速になり(計算量O(1))、大規模なデータセットでも効率的に動作します。用途に応じて使い分けてください。

  1. JavaScriptのlastIndexプロパティとは?正規表現のマッチ位置を取得する方法

    lastIndexプロパティとは JavaScriptにおける「lastIndex」プロパティは、正規表現オブジェクトが持つプロパティの一つで、直前のマッチが終了した位置(インデックス)を返します。そして、次回の検索はその位置から再開されるという仕組みになっています。 重要な注意点として、lastIndexプロパティは「g」(グローバル)フラグが設定されている場合にのみ機能します。「g」フラグがない状態では、lastIndexは常に0のまま変化しないため、連続した検索を行うことができません。 以下は、JavaScriptでlastIndexプロパティを使用する際のコード例です。 サンプルコード

  2. JavaScriptのsourceプロパティとは?正規表現パターンテキストを取得する方法を解説

    JavaScriptのsourceプロパティは、RegExp(正規表現)オブジェクトに設定されたパターン文字列そのものを返すプロパティです。g(グローバルマッチ)やi(大文字・小文字を区別しない)などのフラグは結果に含まれず、マッチング対象となる純粋な正規表現テキストのみを取得できます。 動的に正規表現を組み立てたい場合や、デバッグ時に実際に適用されているパターンを確認したい場合などに活用できる便利なプロパティです。 基本構文 const regex = /pattern/flags; console.log(regex.source); // パターン文字列のみが返される サンプルコード