JavaScriptで配列内の最頻値を求める方法|出現回数が同じ場合は先に現れた値を返す
この記事では、リテラル値の配列を受け取り、最も出現回数の多い値を返すJavaScript関数の作成方法を解説します。出現回数が同じ値が複数存在する場合は、その中で配列内に最初に現れた値を返すのがポイントです。
要件の確認
まず、次のような配列が与えられたケースを見てみましょう。
const arr = ['25', '50', 'a', 'a', 'b', 'c']
この場合、'a' は2回出現しており他の値より多いため、戻り値は 'a' となります。
const arr = ['75', '100', 'a', 'b', 'b', 'a']
一方こちらの例では、'a' と 'b' の出現回数がどちらも2回で同数です。このような場合、配列内で先に登場している 'a' を返す必要があります。
実装コード
上記の要件を満たすコードは次のとおりです。
const arr = ['25', '50', 'a', 'a', 'b', 'c'];
const arr1 = ['75', '100', 'a', 'b', 'b', 'a'];
const getMostFrequentValue = (arr = []) => {
let count = 0, ind = -1;
arr.forEach((el, i) => {
this[el] = this[el] || { count: 0, ind: i };
this[el].count++;
if (this[el].count > count) {
count = this[el].count;
ind = this[el].ind;
return;
};
if (this[el].count === count && this[el].ind < ind) {
ind = this[el].ind;
};
}, Object.create(null));
return arr[ind];
};
console.log(getMostFrequentValue(arr));
console.log(getMostFrequentValue(arr1));
実行結果
コンソールには以下のように出力されます。
a a
コードの仕組み
この関数では、配列を走査しながら各要素ごとに出現回数(count)と最初に出現したインデックス(ind)をオブジェクトに記録していきます。Object.create(null) を使うことで、toString などの組み込みプロパティ名と衝突しないプレーンなオブジェクトを作成できる点も工夫です。
処理の流れを整理すると次のようになります。
- 初めて見つけた要素に対しては
{ count: 0, ind: i }という記録を作成し、カウントを開始します。 - 出現回数が現在の最大値(
count)を上回った場合は、最大カウントとインデックスを更新します。 - 出現回数が同数だった場合は、より小さいインデックス(=配列内で先に現れた要素)を採用することで、「同数なら最初の値を返す」という要件を実現しています。
- 最後に
arr[ind]を返せば、最頻値または同数時に先に現れた値が取得できます。
このように、出現回数のカウントと最初のインデックスを併せて管理することで、シンプルなコードでありながら「最頻値+同数時の優先順位」の両方に対応できるのがこの実装の特徴です。
-
JavaScriptのArray.flatMap()メソッドとは?ネスト配列をフラット化する使い方を実例で解説
JavaScriptのflatMap()メソッドは、ネストされた配列の各要素にコールバック関数を適用し、その結果を1階層だけ平坦化(フラット化)して、新しい配列として返します。「map()」と「flat()」を組み合わせた処理を1つのメソッドで実現できるため、入れ子構造の配列をシンプルに変換したい場合にとても便利です。元の配列は変更されず、常に新しい配列が生成される点も覚えておきましょう。以下は、array.flatMap()メソッドを使った具体的なサンプルコードです。サンプルコード<!DOCTYPE html> <html lang="ja"> &
-
JavaScriptのslice()メソッドとは?配列から要素を取り出す使い方を実例で解説
JavaScriptのslice()メソッドは、大きな配列の中から選択した範囲の要素を抜き出し、新しい配列として返すメソッドです。最大の特徴は、元の配列を一切変更しない(非破壊的な操作)という点にあります。そのため、元データを保持したまま部分的なコピーを作りたい場合に非常に便利です。 slice()メソッドの基本構文 arr.slice(start, end) start:取り出しを開始するインデックス番号(省略可・デフォルトは0) end:取り出しを終了する位置の直前のインデックス番号(省略可・デフォルトは配列の末尾まで)。endで指定した要素自体は結果に含まれない点に注意してください。