JavaScriptで配列内の2番目に頻出する要素を効率的に見つける方法
JavaScriptを使って、配列の中で2番目に多く出現する要素を取得したいケースは意外と多いものです。例えば、アンケートデータの分析やログの集計などで、最頻値だけでなく「次に多い値」を知りたい場面があるでしょう。
この記事では、Mapオブジェクトとreduce()メソッドを組み合わせて、2番目に頻出する要素をシンプルに求める方法を解説します。
実装の考え方
処理の流れは以下の3ステップです。
- 出現回数のカウント:
reduce()を使って各要素の出現回数をMapに記録します。 - 配列への変換:
Array.from()でMapを[キー, 出現回数]のペア配列に変換します。 - 並べ替え: 出現回数の降順にソートし、インデックス1(2番目)の要素を取り出します。
サンプルコード
const arr = [5, 2, 6, 7, 54, 3, 2, 2, 5, 6, 7, 5, 3, 5, 3, 4];
const secondMostFrequent = arr => {
// 各要素の出現回数をMapに集計
const map = arr.reduce((acc, val) => {
if (acc.has(val)) {
acc.set(val, acc.get(val) + 1);
} else {
acc.set(val, 1);
}
return acc;
}, new Map());
// Mapを[要素, 回数]のペア配列に変換し、出現回数の降順でソート
const frequencyArray = Array.from(map);
frequencyArray.sort((a, b) => b[1] - a[1]);
// 2番目に頻出する要素を返す
return frequencyArray[1][0];
};
console.log(secondMostFrequent(arr));
実行結果
コンソールには以下のように出力されます。
2
コードの解説
このサンプル配列では、5が4回、2と3がそれぞれ3回出現しています。そのため最頻値は5、2番目に頻出するのは2となります。
reduce()の初期値として空のMapを渡し、各要素を走査しながら出現回数を更新していくのがポイントです。has()でキーの存在を確認し、既に存在すればget()で現在のカウントを取得して+1、存在しなければ1で新規登録します。
ソートの際は、比較関数(a, b) => b[1] - a[1]によってペアの2番目の要素(出現回数)を降順に並べています。これにより、インデックス0が最頻値、インデックス1が2番目に頻出する要素を指します。
注意点
同率の出現回数が複数ある場合、どの要素が選ばれるかはソートの安定性や元の順序に依存します。厳密な順位付けが必要な場合は、タイブレークのルールを比較関数に追加するとよいでしょう。また、配列の要素数が極端に少ない場合(frequencyArray[1]が存在しない場合)はエラーになるため、事前にバリデーションを行うことをおすすめします。
-
Pythonで最大k回の操作後に実現できる要素の最大頻度を求めるプログラム
問題の概要配列 nums と整数 k が与えられます。1回の操作ごとに、nums 内の任意のインデックスを1つ選び、その位置の要素の値を1だけ増やすことができます。操作は最大 k 回まで行えるとき、最終的にある1つの要素が持ち得る最大の出現頻度(同じ値の個数)を求めてください。たとえば、入力が nums = [8,3,6]、k = 9 の場合、出力は 3 になります。要素 3 を5回、要素 6 を2回増やすことで配列を [8,8,8] にでき、合計7回の操作で頻度3を達成できるためです。アプローチ:ソート+スライディングウィンドウこの問題は、配列をあらかじめソートしておき、スライディングウィン
-
Pythonで隠し配列から最頻出要素のインデックスを求めるプログラムの実装方法
問題概要ここでは、「TestArray」というクラスが与えられた状況を考えます。このクラスは、値として 0 か 1 のみを格納できる非公開(private)の配列を内部に持ち、外部から利用できる公開メンバー関数として length() と query() の2つを提供しています。length():配列の長さを返します。query(p, q, r, s):4つのインデックスを受け取り、それぞれの位置にある値を比較して、次の3種類の値のいずれかを返します。指定された4つのインデックスの値がすべて同じ(すべて 0、またはすべて 1)場合 → 4 を返す3つの値が同じで、残りの1つだけが異なる場合 →