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

JavaScriptで特定のフィールドをマージしながら配列を集約する方法

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

const arr = [{
    id: 121,
    hobby: 'cycling'
}, {
    id: 125,
    hobby: 'jogging'
}, {
    id: 129,
    hobby: 'reading'
}, {
    id: 121,
    hobby: 'writing'
}, {
    id: 121,
    hobby: 'playing football'
}, {
    id: 125,
    hobby: 'cooking'
}, {
    id: 129,
    hobby: 'horse riding'
}];

ここで作成したいのは、このような配列を受け取り、共通する id プロパティを基準に要素をマージする関数です。マージ後の hobby プロパティは配列とし、同じ id に紐づくすべての趣味(hobby)をその配列の中に格納します。

この処理には Array.prototype.reduce() メソッドを使用します。reduce() を使えば、配列を走査しながら同じ id を持つ要素をその場で集約できます。

実装コードは以下の通りです。

サンプルコード

const arr = [{
    id: 121,
    hobby: 'cycling'
}, {
    id: 125,
    hobby: 'jogging'
}, {
    id: 129,
    hobby: 'reading'
}, {
    id: 121,
    hobby: 'writing'
}, {
    id: 121,
    hobby: 'playing football'
}, {
    id: 125,
    hobby: 'cooking'
}, {
    id: 129,
    hobby: 'horse riding'
}];
const mergeArray = (arr) => {
    return arr.reduce((acc, val) => {
        const ind = acc.findIndex(item => item.id === val.id);
        if(ind !== -1){
            acc[ind].hobby.push(val.hobby);
        }else{
            acc.push({
                id: val.id, hobby: [val.hobby]
            });
        };
        return acc;
    }, []);
};
console.log(mergeArray(arr));

出力結果

コンソールには以下のように出力されます。

[
    { id: 121, hobby: [ 'cycling', 'writing', 'playing football' ] },
    { id: 125, hobby: [ 'jogging', 'cooking' ] },
    { id: 129, hobby: [ 'reading', 'horse riding' ] }
]

処理のポイント

このコードの流れを簡単に整理すると、次のようになります。

  1. reduce() の初期値として空配列 [] を渡します。
  2. 各要素について、findIndex() を使って累積配列(acc)の中に同じ id を持つ要素が既に存在するかどうかを確認します。
  3. 存在する場合は、その要素の hobby 配列に現在の趣味を push します。
  4. 存在しない場合は、新しいオブジェクト { id, hobby: [val.hobby] } を acc に追加します。

パフォーマンスに関する補足

上記の実装では要素ごとに findIndex() を呼び出すため、計算量は O(n²) になります。データ件数が少ない場合は問題ありませんが、要素数が多い配列を扱う場合は、Map を使って id をキーとしてグループ化してから配列に変換する方法(O(n))の方が効率的です。

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

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

  2. 【初心者向け】ボタンクリックでJavaScript配列の要素を逆順に1つずつ表示する方法

    JavaScriptの配列を逆順に1つずつ表示するには? 本記事では、ボタンをクリックするたびに、JavaScriptの配列要素を後ろから順に(逆順で)1つずつ表示する方法を解説します。 まず、次のような配列を例として用意しました。 var listOfNames = [    John,    David,    Bob ]; そして、クリックすると配列の値を逆順に取得できるボタンは以下のとおりです。 <button id="reverse" onclick="rev