JavaScriptで要素の出現頻度に基づいて配列を並べ替える方法
概要
本記事では、リテラルの配列を第一引数(唯一の引数)として受け取るJavaScript関数を作成します。対象となる配列には同じ値が繰り返し含まれている可能性があり、作成する関数は出現頻度が低い値ほど前へ、出現頻度が高い値ほど後ろへ配置するように配列を並べ替えるものです。
要件の確認
たとえば、入力配列が次のような場合を考えてみましょう。
const arr = [4, 7, 3, 5, 5, 4, 7, 9, 2, 1, 5, 7, 5, 5, 9];
このとき、期待される出力配列は以下のとおりです。
const output = [ 3, 2, 1, 9, 9, 4, 4, 7, 7, 7, 5, 5, 5, 5, 5 ];
結果を見ると、「3」「2」「1」といった1回しか出現しない値が先頭に配置され、最も多く出現する「5」(5回)が末尾に来ています。また、出現回数が同じ値同士(「3・2・1」や「9・4」など)については、値が大きい方が先に並ぶ仕様になっている点にも注目してください。
サンプルコード
以下が実際の実装コードです。
const arr = [4, 7, 3, 5, 5, 4, 7, 9, 2, 1, 5, 7, 5, 5, 9];
const sortByNumbers = (arr = []) => {
const map = {};
const res = [];
for (let i = 0; i < arr.length; i++) {
map[arr[i]] = map[arr[i]] || [0];
map[arr[i]][0]++;
map[arr[i]][1] = arr[i];
}
const sorted = Object.values(map).sort((a, b) => {
if (a[0] === b[0]) {
return b[1] - a[1];
}
return a[0] - b[0]
});
for (let i = 0; i < sorted.length; i++) {
const [freq, num] = sorted[i]
for (let j = 0; j < freq; j++) {
res.push(num);
}
}
return res;
};
console.log(sortByNumbers(arr));コードの解説
このコードの処理は、大きく次の3つのステップで構成されています。
- 出現回数の集計: まずオブジェクト
mapを用意し、配列を走査しながら各値ごとに出現回数(インデックス0)と値そのもの(インデックス1)を記録していきます。 - ソート処理:
Object.values()で集計結果を配列として取り出し、出現回数の昇順にソートします。出現回数が同一の場合はb[1] - a[1]の比較により、値の降順で並ぶように制御しています。 - 結果配列の構築: 最後にソート済みのデータを順番に走査し、各値を出現回数の分だけ結果配列
resへ追加していきます。
計算量としては、要素の集計にO(n)、ソートにO(k log k)(kはユニークな値の種類数)かかるため、全体として効率的な処理となっています。
実行結果
上記コードを実行すると、コンソールには次のように出力されます。
[ 3, 2, 1, 9, 9, 4, 4, 7, 7, 7, 5, 5, 5, 5, 5 ]
期待どおり、出現回数が少ない値から順に並び替えられていることが確認できます。
-
JavaScriptで配列を出現頻度の昇順に並べ替える方法
問題数値の配列 arr を唯一の引数として受け取るJavaScript関数を作成する必要があります。配列 arr には重複した要素が含まれている可能性があります。この関数では、出現回数が少ない要素から順に配列を並べ替えます。つまり、出現頻度の低い要素を先頭に配置し、頻度の昇順に沿って残りの要素を並べていきます。なお、出現回数が同じ要素が複数存在する場合は、それらを値の昇順(小さい順)に配置する必要があります。入力例const arr = [5, 4, 5, 4, 2, 1, 12];出力例[1, 2, 12, 4, 4, 5, 5]出力の解説数値「1」「2」「12」はそれぞれ1回しか出現しない
-
Pythonで要素の出現頻度が少ない順に配列をソートするプログラム
問題の概要 同じ要素が複数回出現する可能性のある配列が与えられたとします。この配列を、出現頻度が少ない順(頻度の昇順)に並べ替えることを考えます。つまり、出現回数が最も少ない要素から先に並べ、以降も頻度の昇順に従ってソートしていきます。 例えば、入力が nums = [1,5,3,1,3,1,2,5] の場合、出力は [2, 5, 5, 3, 3, 1, 1, 1] となります。 この例では、「2」は1回、「5」と「3」はそれぞれ2回、「1」は3回出現します。そのため、頻度の少ない順に「2 → 5 → 3 → 1」の順で並びます。なお、同じ頻度の要素同士(5と3)は、値の大きい方から先に並ぶ点