この種の要件が発生し、配列内の重複した要素を削除して 1 つだけを保持する必要がある場合があります。最初に思い浮かぶのは、2 つの for ループを使用して重複要素を比較して削除することでしょう。コードは次のとおりです。
方法 1:
Array.prototype.distinct = function() {
var arr = [],
len = this.length;
for ( var i = 0; i for( var j = i 1; 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 は、sort のカスタム コールバック関数を使用し、IE6/7/8 がサポートしていないメソッドである IndexOf も使用します。もちろん、indexOf を自分でシミュレートすることもできますが、より大きな問題は、IE6/7/8 と標準ブラウザーのソート方法に違いがあることです。 IE6/7/8 の sort メソッドを使用するカスタム コールバック関数には、多くのトラップがあります。IE6/7/8 では、上記のカスタム ソート コールバック関数のコードが、コールバック関数の戻り値の「数値不足」エラーを直接報告します。 NaN の場合、理論的にはソート コールバック関数は整数のみを返すことができるため、このエラーが報告されます。戻り値の問題を無視したとしても、最終的には、方法 2 は IE6/7/8 では機能しません。
Fool's Wharf のメソッド 3 を参照してください。コードは次のとおりです:
Array.prototype.delRepeat=function(){
var newArray=[];
var PrimaryTable = {};
for (var i = 0, item; (item= this[i]) != null; i ) {
if (!provisionalTable[item]) {
newArray.push(item);
priorityTable[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
result = this[i];
if( obj[result] !== result ){
arr.push( result );
obj[結果] = 結果;
}
}
return arr;};
次に、Fool's Wharf の記事の最後にあるコメントを読みました。この方法は Rekey が提供する方法と同じですが、この方法にもバグがあります。このような 2B 配列に遭遇すると、大惨事になります。
var arr = [ 'firefox', 1 , '1 ', 1 ];
上記の配列に方法 3 の修正版を使用すると、最後の 3 つの要素は削除されません。ただし、この種の配列は少し極端です。同じ文字列リテラルと数値を持つデータが見つかった場合は、事前に次のようにする必要があります。 -これを回避するために処理してください。一時オブジェクトを使用する方法は、標準ブラウザでの並べ替えよりもわずかに高速であり、各ブラウザの並べ替え方法のアルゴリズムも異なるはずです。