javascript配列は重い方法の最終総括に行きます.
2682 ワード
このような需要にぶつかることがあります.配列中の重複した要素を削除し、一つだけ残しておく必要があります.最初に考えた方法はおそらく2つのfor循環で比較して重複した要素を除去することです.コードは以下の通りです.
方法1:
方法2:
エイプリルフール埠頭から方法3を見ました.以下は彼のコードです.
方法1:
Array.prototype.distinct = function(){
var arr = [],
len = this.length;
for ( var i = 0; i < len; i++ ){
for( var j = i+1; j < len; j++ ){
if( this[i] === this[j] ){
j = ++i;
}
}
arr.push( this[i] );
}
return arr;
};
使用方法1データが多い場合、性能に大きな差があります.では、次の方法を引き続き見てください.方法2:
Array.prototype.distinct = function(){
var self = this,
arr = self.concat().sort(); //
arr.sort(function( a, b ){
if( a === b ){
var n = self.indexOf( a ); //
self.splice( n, 1 );
}
});
return self;
};
方法2は、ソトのカスタムコール関数を使用しており、indexOfというIE 6/7/8がサポートされていない方法も用いられている.もちろん、indexOfは自分でシミュレーションできますが、もっと大きな問題はIE 6/7/8のsort方法と標準ブラウザの間にも違いがあります.IE 6/7/8では、ソトメソッドを使用したカスタムチューニング関数の落とし穴が多く、上記のカスタムソトのコールバック関数のコードは、IE 6/7/8で直接に「数字が足りない」エラーを報告します.コールバック関数の戻りはNaNであればこのエラーを報告します.理論上、ソトのコールバック関数は整数に戻ります.戻り値を無視しても他の問題があります.最後にあまりもつれないようにします.方法2はIE 6/7/8では通じません.エイプリルフール埠頭から方法3を見ました.以下は彼のコードです.
Array.prototype.delRepeat=function(){
var newArray=[];
var provisionalTable = {};
for (var i = 0, item; (item= this[i]) != null; i++) {
if (!provisionalTable[item]) {
newArray.push(item);
provisionalTable[item] = true;
}
}
return newArray;
};
方法3は、配列の要素を保存するための一時的なオブジェクトを使用しています.重複する配列要素に触れると無視されます.しかし、次のような配列に当たると、
var arr = [ 'firefox', 1, '1' ];
上の配列は方法3で1と1を重複要素として誤って削除しますので、方法3を少し修正しました.このバグを解決できます.方法3の修正版:
Array.prototype.distinct = function(){
var arr = [],
obj = {},
i = 0,
len = this.length,
result;
for( ; i < len; i++ ){
result = this[i];
if( obj[result] !== result ){
arr.push( result );
obj[result] = result;
}
}
return arr;
};
その後、エイプリルフール埠頭の記事の後ろのコメントを見ました.この方法はRekeyが提供する方法と同じです.しかし、この方法はBUGもあります.このような2 B配列に遭遇すると、杯具になります.
var arr = [ 'firefox', 1, '1', 1 ];
上の配列用方法3の修正版は、後の3つの要素は削除されませんが、この配列は極端です.文字列の字面量と数字が同じデータがあれば、このバグを回避するために予め処理しておきます.一時的なオブジェクトを使う方法は、標準ブラウザよりもやや速く、各ブラウザでのsort方法のアルゴリズムにも違いがあるはずです.