前回「JavaScript 配列の uniq メソッド」という記事を書きましたが、コードの問題がまだ存在することがわかりました。たとえば、配列内に未定義の要素がある場合、フィルタリングできません。
昨日、Brother Lazy が関数を更新したのを見ましたが、今は次のように書いています。
Array.prototype.uniq = function() {
var resultArr = [],
returnArr = [],
origLen = this.length,
resultLen;
function include(arr, value) {
for (var i = 0, n = arr.length; i return false;
}
resultArr.push(this[0]);
for (var i = 1; i if (include(resultArr, this[i])) {
returnArr.push(this[i]);
} else {
resultArr.push(this[i]); > }
}
resultLen = resultArr.length;
this.length = resultLen;
for (var i = 0; i this[i ] = resultArr[i];
return returnArr;
}彼によると、「この解決策は、プロセス全体で元の配列を 2 回変更するだけで、効率は約 2 です」他の 2 つよりも桁違いに高いです!」ということで、この関数の効率を実際に測定しました。確かに (接続ポイントのテストはここにあります)。
関数も書き直して更新しました。次のようになります。
Array.prototype.uniq = function() {
var tmp = new Array; var length = this.length;
for(var i = 0; i var Push = true;
for(var j = i 1; j }
if(push) {
tmp.push(this[i])
}
}
this.length = tmp。長さ; for (var i = 0; i this[i] =
}
return
同じページからテストしたところ、効率は依然として Lazy 兄弟の効率であり、わずかに高速です。少し考えた後、いくつかのアイデアがあります。
ネストする関数は関数から独立させることができます (Lazy 兄弟の include 関数と同じように)。上記の場合、ループ判定よりも関数を呼び出した方が効率的です。
データ量が大きい場合、配列に対して周期的な読み取りおよび書き込み操作を実行する場合は、効率の問題に特別な注意を払う必要があります。
怠惰な兄弟の結論:
可能であれば、配列を変更するとコストがかかります。元の配列を変更しないようにしてください。
最終的に配列自体を変更する必要がある場合は、結果を元の配列に割り当てて操作できます。なお、長さ
の計算に関しては、効率には影響がないようです。 Brother Lazy の resultArr 配列は、彼の記述方法に従って同じ値を保存できます (ただし、私の関数は少し変更するだけで実装できます)。興味のある友達は Lazy のページにアクセスして見てください。
最後に、Wang Yuantao 兄弟による JavaScript 配列の uniq メソッドを読むことをお勧めします。ありがとうございました。