首先讓我們看下 YUI 是如何處理的:
var toObject = function(a) {
var o = {};
for (var i = 0; i < a.length; i = i+1) {
o[a[i]] = true;
}
return o;
};
var keys = function(o) {
var a=[], i;
for (i in o) {
if (lang.hasOwnProperty(o, i)) { // YUI的方法
a.push(i);
}
}
return a;
};
var uniq = function(a) {
return keys(toObject(a));
};
詳細(xì)分析,見(jiàn)同事 長(zhǎng)天 的分享 《巧妙去除數(shù)組中的重復(fù)項(xiàng)》。
自己使用的方式與 YUI 的方式十分相似,不過(guò)僅使用了一次循環(huán)便完成了刪除數(shù)組中重復(fù)項(xiàng),如下:
var uniq = function (arr) {
var a = [],
o = {},
i,
v,
len = arr.length;
if (len < 2) {
return arr;
}
for (i = 0; i < len; i++) {
v = arr[i];
if (o[v] !== 1) {
a.push(v);
o[v] = 1;
}
}
return a;
}
經(jīng)過(guò)了簡(jiǎn)單的測(cè)試:自己使用的方式性能遠(yuǎn)遠(yuǎn)高于 YUI 的方式。
拋磚引玉,歡迎大家提供更好的處理方法。
2009年12月28日更新:
以上兩種函數(shù)方法暫時(shí)都不能處理復(fù)雜的含有混合類(lèi)型的數(shù)組(感謝 小貓 提出的疑問(wèn)),如:[0,"0",1,"1",0]、["null",null]。
對(duì)于能夠約定類(lèi)型為數(shù)字(注:要求非0開(kāi)頭的數(shù)字,小數(shù)除外)或字符串的數(shù)組,我們可以用改進(jìn)后的函數(shù)方法(感謝 closurecache 提供的思路):
var uniq = function (arr) {
var a = [],
o = {},
i,
v,
cv, // corrected value
len = arr.length;
if (len < 2) {
return arr;
}
for (i = 0; i < len; i++) {
v = arr[i];
/* closurecache 提供的函數(shù)中使用的是 cv = v + 0;,
* 這樣就無(wú)法辨別類(lèi)似[1, 10, "1", "10"]的數(shù)組,
* 因?yàn)檫\(yùn)算后 => 1, 10, 10, 100,很明顯,出現(xiàn)了重復(fù)的標(biāo)示符。
* 加前面就難道沒(méi)問(wèn)題嗎?
* 有的:數(shù)組中不能出現(xiàn)類(lèi)似01 、001,以 0 開(kāi)頭的數(shù)字,
* 但適用性比原先更廣。
*/
cv = 0 + v;
if (!o[cv]) {
a.push(v);
o[cv] = true;
}
}
return a;
}
如果大家想在此解題思路的基礎(chǔ)上,更完美一點(diǎn),推薦 Dexter.Yy 的方法,進(jìn)行類(lèi)型判斷,給予唯一標(biāo)示符,詳見(jiàn) 評(píng)論 20 樓。
沒(méi)有最好,只有最合適的方式,其實(shí)使用 Array.indexOf() 的思路也是不錯(cuò)的選擇,對(duì)于已經(jīng)支持的瀏覽器直接用原生的 Array.indexOf() 方法,對(duì)于未支持的,我們?cè)黾?Array.indexOf() 方法,如下:
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length + fromIndex);
}
for (var i = fromIndex; i < this.length; i++) {
if (this[i] === obj)
return i;
}
return -1;
};
}
接下來(lái),實(shí)現(xiàn)的過(guò)程就非常簡(jiǎn)單了。
對(duì)于使用 Array.indexOf() 方法實(shí)現(xiàn)方案的優(yōu)化提示:找到相同值時(shí),從數(shù)組中移除,以減少下次遍歷的量。