はじめに
JavaScriptの配列内に、どんな要素が何個あるのか、重複している値の個数をカウント。
その結果をオブジェクト(連想配列)に格納します。
for
・forEach
・reduce
の三種類の方法で書いてみます。
処理パターン
for でカウント
for
var arr = [0, 1, 1, 1, 1, 3, 3, 5, 0, 7];
var count = {};
for (var i = 0; i < arr.length; i++) {
var elm = arr[i];
count[elm] = (count[elm] || 0) + 1;
}
console.log(count);
// 出力結果
// {0: 2, 1: 4, 3: 2, 5: 1, 7: 1}
// 0 -> 2個
// 1 -> 4個
// 3 -> 2個
// 5 -> 1個
// 7 -> 1個
カウント部分の(count[elm] = count[elm] || 0) + 1;
の記述は、論理演算子の短絡評価を利用して、以下のよう処理しています。
- count[elm]がある => count[elm]の現在値+1を格納。(既にカウントを開始している要素)
- count[elm]がない => count[elm]に1(0+1)を格納。(初めてカウントする要素:値は
undefined
)
以下のように三項演算子で書いても結果は同じになります。
カウントの部分
// 論理演算子を使う
count[elm] = (count[elm] || 0) + 1;
// 三項演算子を使う
count[elm] = count[elm] ? count[elm] + 1 : 1;
forEach でカウント
forEach
var arr = [0, 1, 1, 1, 1, 3, 3, 5, 0, 7];
var count = {};
arr.forEach(function(i) {
count[i] = (count[i] || 0) + 1;
});
console.log(count);
// 出力結果
// {0: 2, 1: 4, 3: 2, 5: 1, 7: 1}
reduce でカウント
reduce
var arr = [0, 1, 1, 1, 1, 3, 3, 5, 0, 7];
var count = arr.reduce(function(prev, current) {
prev[current] = (prev[current] || 0) + 1;
return prev;
}, {});
console.log(count);
// 出力結果
// {0: 2, 1: 4, 3: 2, 5: 1, 7: 1}
おわりに
JavaScriptのループ処理速度は便利なforEach
より、ループの基本であるfor
の方が速いようです。シンプル・イズ・ベスト?と言ったところでしょうか。
カウントしたい配列の要素数が数万個あると言ったケースに遭遇することもあります。要素数が多いときは、速度重視のfor
で処理することも検討してみましょう。