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

JavaScriptで配列をグループ化し、ユニークなユーザー数をカウントして新しい配列を作成する方法

JavaScriptでオブジェクトの配列を扱う際、特定のプロパティを基準にデータをグループ化し、それぞれのグループ内のユニークな要素をカウントしたい場面はよくあります。本記事では、そのような処理を実現する関数の実装方法を解説します。

問題の概要

まず、次のようなオブジェクトの配列があると仮定しましょう。

const arr = [
    { region: "Africa", fruit: "Orange", user: "Gary" },
    { region: "Africa", fruit: "Apple", user: "Steve" },
    { region: "Europe", fruit: "Orange", user: "John" },
    { region: "Europe", fruit: "Apple", user: "bob" },
    { region: "Asia", fruit: "Orange", user: "Ian" },
    { region: "Asia", fruit: "Apple", user: "Angelo" },
    { region: "Africa", fruit: "Orange", user: "Gary" }
];

この配列に対して、「region(地域)」プロパティを基準にデータをグループ化した新しいオブジェクトの配列を作成するJavaScript関数が必要です。

さらに、各地域ごとのユニークなユーザー数もカウントする必要があります。つまり、同じ地域内で同じユーザーが複数回出現した場合は、1人として数えるという要件です。

期待される出力

上記の配列の場合、出力は次のようになります。なお、最後の「Gary」はアフリカ地域に重複しているため、Africa のカウントには含まれません。

const output = [
    {
        "region": "Africa",
        "count": 2
    },
    {
        "region": "Europe",
        "count": 2
    },
    {
        "region": "Asia",
        "count": 2
    }
];

実装コード

この問題を解くコードは以下の通りです。

const arr = [
    { region: "Africa", fruit: "Orange", user: "Gary" },
    { region: "Africa", fruit: "Apple", user: "Steve" },
    { region: "Europe", fruit: "Orange", user: "John" },
    { region: "Europe", fruit: "Apple", user: "bob" },
    { region: "Asia", fruit: "Orange", user: "Ian" },
    { region: "Asia", fruit: "Apple", user: "Angelo" },
    { region: "Africa", fruit: "Orange", user: "Gary" }
];
const groupByArea = (arr = []) => {
    const res = [];
    arr.forEach(el => {
        let key = [el.region, el.user].join('|');
        if (!this[el.region]) {
            this[el.region] = { region: el.region, count: 0 };
            res.push(this[el.region]);
        };
        if (!this[key]) {
            this[key] = true;
            this[el.region].count++;
        };
    }, Object.create(null));
    return res;
}
console.log(groupByArea(arr));

コードの解説

この実装のポイントを順番に見ていきましょう。

1. ユニークキーの生成: [el.region, el.user].join('|') によって、地域とユーザーの組み合わせから一意なキー(例:Africa|Gary)を生成しています。これにより、同じユーザーが同じ地域で重複してカウントされるのを防ぎます。

2. グループの初期化: this[el.region] が存在しない場合、つまりその地域がまだ処理されていない場合は、{ region, count: 0 } 形式の新しいエントリを作成し、結果配列 res に追加します。

3. カウントの更新: 地域とユーザーの組み合わせキーが未登録の場合のみ、count をインクリメントします。これにより、ユニークなユーザーだけが正確に数えられます。

4. プロトタイプ汚染の防止: Object.create(null) を第2引数として渡すことで、this がプロトタイプチェーンを持たないプレーンなオブジェクトになるようにしています。これは、toString などの組み込みプロパティとの衝突を避けるための安全策です。

実行結果

コンソールに出力される結果は以下の通りです。

[
    { region: 'Africa', count: 2 },
    { region: 'Europe', count: 2 },
    { region: 'Asia', count: 2 }
]

各地域に2人のユニークなユーザーが存在するため、すべての地域で count: 2 となっています。重複した「Gary」のレコードは正しく除外されていることが確認できます。

まとめ

このように、forEach とハッシュマップ的なオブジェクトを組み合わせることで、配列のグループ化とユニークカウントを効率的に実装できます。データ量が多い場合は、Map オブジェクトや reduce メソッドを使った代替実装も検討するとよいでしょう。

  1. JavaScriptでnewキーワードを使って配列を作成する方法

    JavaScriptでは、newキーワードとArray()コンストラクタを使用することで、簡単に配列を作成できます。本記事では、実際に動作するサンプルコードとともに、その基本的な使い方を解説します。 サンプルコード 以下は、newキーワードを使用してJavaScriptの配列を作成するコード例です。 <!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=device-width, initial-sca

  2. JavaScriptでオブジェクトを新しい配列に変換する方法

    JavaScriptでは、オブジェクトのプロパティやネストされたデータを取り出し、扱いやすい形で新しい配列にフォーマットできます。本記事では、学校(school)オブジェクトに含まれる生徒情報を、文字列形式の配列へ変換する実践的なコード例を紹介します。 ポイントとなるテクニック このサンプルでは、以下の2つのJavaScript機能を活用しています。 分割代入(Destructuring assignment):オブジェクトから特定のプロパティを簡潔に取り出す構文です。 for...of ループ:配列内の各要素を順番に処理するために使用します。 コード例 <!DOCTYPE html