配列の重複するメンバーをフィルター
重要度:4
arr
を配列とします。
unique(arr)
という関数を作り、この関数はarr
の一意のアイテムを含む配列を返します。
例
function unique(arr) {
/* your code */
}
let strings = ["Hare", "Krishna", "Hare", "Krishna",
"Krishna", "Krishna", "Hare", "Hare", ":-O"
];
alert( unique(strings) ); // Hare, Krishna, :-O
配列のアイテムをたどってみましょう。
- 各アイテムについて、結果の配列にそのアイテムが既に存在するかどうかをチェックします。
- そうなっている場合、無視、そうでなければ結果に追加します。
function unique(arr) {
let result = [];
for (let str of arr) {
if (!result.includes(str)) {
result.push(str);
}
}
return result;
}
let strings = ["Hare", "Krishna", "Hare", "Krishna",
"Krishna", "Krishna", "Hare", "Hare", ":-O"
];
alert( unique(strings) ); // Hare, Krishna, :-O
コードは機能しますが、潜在的なパフォーマンスの問題があります。
result.includes(str)
メソッドは内部的に配列result
をたどり、マッチングを見つけるために各要素をstr
と比較します。
つまり、result
に100
の要素があり、誰もstr
と一致しない場合、result
全体をたどり、ちょうど100
の比較を行います。そしてresult
が10000
のように大きい場合、10000
の比較があります。
それ自体は問題ではありません。JavaScriptエンジンは非常に高速なので、10000
の配列を歩くのはマイクロ秒の問題です。
しかし、for
ループ内のarr
の各要素についてこのようなテストを行います。
つまり、arr.length
が10000の場合、10000 * 10000 = 1億の比較が行われます。これは多いですね。
つまり、この解決策は小さな配列にのみ適しています。
以降の章、Map and Setでは、これを最適化する方法を検討します。