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

JavaScriptでオブジェクトの配列を「役割ごとの配列」を持つオブジェクトに変換する方法


チームに関するデータが、以下のように「オブジェクトの配列」として与えられているとします。今回の課題は、このデータを「役割(role)をキー、選手名の配列を値」と持つオブジェクトへ変換することです。いわゆるグループ化処理と呼ばれるもので、実務のデータ整形でも頻繁に登場するテクニックなので、ぜひマスターしておきましょう。

サンプルデータ

const team = [{
    role: 'Batsman',
    player: 'V Kohli'
}, {
    role: 'Wicket Keeper',
    player: 'KL Rahul'
}, {
    role: 'Batsman',
    player: 'R Sharma'
}, {
    role: 'Wicket Keeper',
    player: 'R Pant'
}, {
    role: 'Bowler',
    player: 'B Kumar'
}, {
    role: 'Bowler',
    player: 'M Shami'
}];

objectify() 関数の定義

まずは基本形として、配列を引数として受け取り、対応するオブジェクトを返す関数 objectify() を定義します。考え方はシンプルで、各要素を順に走査しながら、役割ごとに選手名を振り分けていくだけです。

コードは次のようになります。

const objectify = (team) => {
    const teamObject = {};
    team.forEach(member => {
        if(teamObject[member.role]){
            teamObject[member.role].push(member.player);
        }else{
            teamObject[member.role] = [member.player];
        }
    });
    return teamObject;
}
console.log(objectify(team));

処理の流れ

  1. 空のオブジェクト teamObject を用意します。
  2. forEach() で配列の各要素(メンバー)を1件ずつ取り出します。
  3. そのメンバーの役割(role)が teamObject のキーとして既に存在すれば、値の配列に push() で選手名を追加します。
  4. まだ存在しない場合は、新しいキーを作成し、選手名1人だけを含む配列を代入します。
  5. すべての要素を処理し終えたら、完成したオブジェクトを返します。

完全なコード例

const team = [{
    role: 'Batsman',
    player: 'V Kohli'
}, {
    role: 'Wicket Keeper',
    player: 'KL Rahul'
}, {
    role: 'Batsman',
    player: 'R Sharma'
}, {
    role: 'Wicket Keeper',
    player: 'R Pant'
}, {
    role: 'Bowler',
    player: 'B Kumar'
}, {
    role: 'Bowler',
    player: 'M Shami'
}];

const objectify = (team) => {
    const teamObject = {};
    team.forEach(member => {
        if(teamObject[member.role]){
            teamObject[member.role].push(member.player);
        }else{
            teamObject[member.role] = [member.player];
        }
    });
    return teamObject;
}
console.log(objectify(team));

出力結果

このコードを実行すると、コンソールには次のように表示されます。

{
    Batsman: [ 'V Kohli', 'R Sharma' ],
    WicketKeeper: [ 'KL Rahul', 'R Pant' ],
    Bowler: [ 'B Kumar', 'M Shami' ]
}

同じ役割を持つ選手たちが、それぞれひとつの配列にまとめられていることが確認できます。

補足: reduce() を使った別解

同じ処理は、Array.prototype.reduce() を使えばより関数型らしいスタイルで書くこともできます。

const objectify = (team) =>
  team.reduce((acc, { role, player }) => {
    (acc[role] ??= []).push(player);
    return acc;
  }, {});

論理null代入演算子 ??=(ES2021以降)を使えば、「キーが未登録なら空配列で初期化してから追加する」という処理を1行で表現できます。どちらの書き方でも結果は同じなので、プロジェクトのコーディング規約や可読性に合わせて選択するとよいでしょう。


  1. 【JavaScript入門】複数のオブジェクトを1つにマージして単一のオブジェクト配列を作成する方法

    JavaScriptでは、Object.assign()メソッドとスプレッド構文(...)を組み合わせることで、配列内の複数のオブジェクトを1つのオブジェクトに簡単にマージすることができます。 Object.assign()は、1つ以上のコピー元オブジェクトから、コピー先のオブジェクトへすべてのプロパティをコピーするためのメソッドです。スプレッド構文を使って配列の要素を展開することで、各オブジェクトのキーと値が1つのオブジェクトに統合されます。 コード例 以下のコードは、配列内の複数のオブジェクトを単一のオブジェクトにマージする例です。 <!DOCTYPE html> <ht

  2. 【Java】Stream.concatを使って配列を新しいオブジェクト配列にマージする方法

    Javaでは、Stream.concatメソッドとArrays.streamメソッドを組み合わせることで、複数の配列を簡単に1つの新しいオブジェクト配列へマージ(結合)できます。元の配列を変更せずに済むため、安全かつ簡潔に処理できるのが特徴です。以下は、Javaで2つの配列を新しいオブジェクト配列にマージするプログラムの例です。サンプルコードimport java.util.stream.Stream; import java.util.Arrays; import java.io.*; public class Demo{     public sta