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

【JavaScript】スペース区切りの文字列から要素の出現頻度をカウントする方法

問題の概要

次のように、空白(スペース)で区切られた複数の文字を含む文字列があるとします。

const str = 'a b c d a v d e f g q';

このような文字列を引数として受け取り、各要素とその出現回数をペアにしたオブジェクトの配列(頻度配列)を返すJavaScript関数を作成しましょう。出現回数が多い順に並べ替えて返すのがポイントです。

実装コード

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

const str = 'a b c d a v d e f g q';

const countFrequency = (str = '') => {
    const result = [];
    const hash = {};
    const words = str.split(' ');

    words.forEach(function (word) {
        word = word.toLowerCase();
        if (word !== '') {
            if (!hash[word]) {
                hash[word] = { name: word, count: 0 };
                result.push(hash[word]);
            }
            hash[word].count++;
        }
    });

    return result.sort((a, b) => b.count - a.count);
}

console.log(countFrequency(str));

コードの解説

処理の流れを順番に見ていきましょう。

  1. 文字列の分割: split(' ') を使って、元の文字列をスペースで分割し、個々の要素の配列を取得します。
  2. 大文字・小文字の統一: toLowerCase() で各要素を小文字に変換し、「A」と「a」を同じものとして扱えるようにします。
  3. ハッシュによる重複チェック: オブジェクト hash をキャッシュとして利用し、まだ登場していない要素の場合のみ、新しいオブジェクト { name: word, count: 0 } を生成して結果配列 result に追加します。
  4. カウントの更新: 既に出現済みの要素であれば、該当オブジェクトの count をインクリメントして出現回数を記録していきます。
  5. ソート: 最後に sort() を使って、count の降順(多い順)に並べ替えた結果を返します。

この手法では各要素を一度だけ走査すればよいため、計算量は O(n) となり、大量のデータでも高速に処理できます。

出力結果

コンソールには次のように表示されます。

[
    { name: 'a', count: 2 },
    { name: 'd', count: 2 },
    { name: 'b', count: 1 },
    { name: 'c', count: 1 },
    { name: 'v', count: 1 },
    { name: 'e', count: 1 },
    { name: 'f', count: 1 },
    { name: 'g', count: 1 },
    { name: 'q', count: 1 }
]

「a」と「d」だけが2回出現しており、それ以外の要素は1回ずつカウントされていることが確認できます。また、出現回数の多い要素が先頭に来るようソートされています。

別の書き方: Mapを使った簡潔な実装

Map オブジェクトを利用すると、よりモダンで簡潔なコードに書き換えることもできます。

const str = 'a b c d a v d e f g q';

const countFrequency = (str = '') => {
    const map = new Map();

    str.split(' ').forEach(word => {
        if (word) {
            map.set(word, (map.get(word) || 0) + 1);
        }
    });

    return [...map]
        .map(([name, count]) => ({ name, count }))
        .sort((a, b) => b.count - a.count);
};

console.log(countFrequency(str));

Map 版は挿入順が保持されるためコードの見通しが良くなりますが、どちらの実装も計算量は O(n) です。用途やチームのコーディングスタイルに合わせて選択するとよいでしょう。

まとめ

この記事では、スペース区切りの文字列から各要素の出現頻度をカウントし、出現回数の降順でソートした配列を返すJavaScript関数を紹介しました。split() での分割、ハッシュ(オブジェクトまたは Map)による集計、sort() での並べ替えという3つのステップが基本構成になります。ログ解析やタグクラウドの生成など、テキストデータの頻度集計が必要な場面で幅広く応用できるテクニックなので、ぜひ活用してください。

  1. JavaScriptのSymbol.for()関数とは?グローバルシンボルレジストリの仕組みと使い方

    Symbol.for()関数は、ランタイム全体で共有されるグローバルシンボルレジストリから、指定されたキーに対応するシンボルを検索するための関数です。 検索の結果、該当するシンボルがすでに登録されていればそれを返し、存在しない場合は新しいシンボルをレジストリに登録したうえで返します。この仕組みにより、異なるスコープやモジュール間でも同じキーを持つシンボルを共有できるようになります。 Symbol.for()とSymbol()の違い 通常のSymbol()呼び出しは、同じ引数を渡しても毎回まったく別の新しいシンボルを生成します。一方、Symbol.for(key)は同じキーを渡せば必ず同じシンボ

  2. PHPのcount()関数の使い方をわかりやすく解説

    PHPのcount()関数は、配列の要素数やオブジェクトのプロパティ数を取得するための関数です。指定した配列に含まれる要素の数を整数値で返します。構文 count(arr, mode) パラメータarr − 要素数を調べたい対象の配列を指定します。mode − カウントのモードを指定します(省略可能)。指定できる値は以下の2つです。0(デフォルト): 通常のカウント。多次元配列の子要素は再帰的に数えません。1: 再帰的なカウント。多次元配列の場合、入れ子になったすべての要素を数えます。戻り値count()関数は、配列内の要素数を整数として返します。使用例次のサンプルコードでは、「Electro