配列の重複するメンバーをフィルター
重要度: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では、これを最適化する方法を検討します。