【コーディング試験頻出】JavaScriptでGROUP BYをする最もシンプルな方法

この記事では、JavaScriptを使ったGROUP BY的な処理を書く上で、おそらくもっともシンプルであろう書き方をご紹介します。

実際アプリを開発するときは、だいたいSQLでGROUP BYをしますし、もし仮にJavaScript側でGROUP BYをする必要が出てきたときも、だいたいLodashとかのライブラリを使う人が多いかもしれません。

にも関わらず、なぜJavaScriptでGROUP BYをする方法を覚えるかというと、企業のコーディング試験にまぁまぁ出題されるからです。

純粋なSoftware Engineer職では、データ構造やアルゴリズムなどもう少し突っ込んだ問題が出題されますが、Technical ConsultantやArchitectなどの職種では、基本的なプログラミングスキルを確認するために、GROUP BY処理などの少し簡単めなプログラミング問題が出題されがちです。

※言語は、基本的なサーバーサイド言語もしくはJavaScriptから好きなものを選択できる)

しかし、普段からSQLとかライブラリでやっているといざというときに、「あれ?どうやって実装すればいいんだ・・・」と混乱してしまいます。

今回ご紹介するJavaScriptによるGROUP BY方法を暗記していただいて、転職に役立てていただければと思います。

文章の中から単語ごとの出現回数を求める問題

これは、例えば、”I I am am am Mike” という文章があったときに、各単語(I, am, Mike)の出現回数を求めます。なので、期待される結果は、{“I”: 2, “am”: 3, “Mike”: 1} というものです。

これは、一旦文章を配列に変換して、それをパースすることで出現回数を求めます。

まずは、文章をスペース区切りでsplitして、配列にしましょう。

var sentence = "I I am am am Mike";
var words = sentence.split(" ");
// ["I", "I", "am", "am", "am", "Mike"]

次はreduceを使って一気に処理していきましょう。

var counts = words.reduce(function(stats, word) {
    if (stats.hasOwnProperty(word)) {
        stats[word]++;
    } else {
        stats[word] = 1;
    }
    return stats;
}, {});

処理の流れ的には以下のような感じです。

  1. wordsの中から1単語ずつ抽出して、statsの中にすでにオブジェクトを持っているか確認する。
  2. なければ、新しく要素を作成する。
  3. あれば、その値に+1する。
  4. 最後にstatsをreturnする。

これによってcountsの中身は以下のような形になります。

{I: 2, am: 3, Mike: 1}

ちなみにreduceの第2引数に入っている {} はstatsの初期値となっているのでこれも覚えておきましょう。

ECサイトの購入トランザクションデータからユーザーごとの購入金額を求める問題

これは出現回数問題とは違い、inputデータが単純な配列ではなく、以下のようなオブジェクト配列になります。

var purchases = [{
        "userID": 100,
        "amount": 10
    },
    {
        "userID": 101,
        "amount": 10
    },
    {
        "userID": 100,
        "amount": 20
    },
];

これも上記のreduceを少し応用するだけで処理することができます。

var counts = purchases.reduce(function(stats, purchase) {
    if (stats.hasOwnProperty(purchase["userID"])) {
        var userID = purchase["userID"];
        var amount = purchase["amount"];
        stats[userID] += amount;
    } else {
        var userID = purchase["userID"];
        var amount = purchase["amount"];
        stats[userID] = amount;
    }
    return stats;
}, {});

結果は暗算できますが、こんな感じですね。

{100: 30, 101: 10}

この記事では、2種類のJavaScriptによるGROUP BY方法をご紹介しました。覚えておいて損はないので、コーディング試験前日などに、おさらい程度に覚えておくと良いかもしれません。

参考記事

word frequency in javascript