總結(jié)一下利用JS解決去重問題的方法岸啡。
總體思路:
- 構(gòu)建一個(gè)新的空數(shù)組阎毅。
- 遍歷數(shù)組,將不重復(fù)的元素Push到新數(shù)組中梅割。
- 返回新建的數(shù)組启盛。
1蹦掐、最直接的寫法,嵌套循環(huán)
寫嵌套循環(huán)是最直接但是也是效率最不高的方法僵闯,第一層循環(huán)中一個(gè)一個(gè)取出原數(shù)組的元素卧抗,第二層循環(huán)中判斷新數(shù)組中是否已經(jīng)存在該元素,若不存在鳖粟,則將新的元素Push進(jìn)新的數(shù)組中去社裆。
var array = ["a","a","2","2",1,2,3,4,4,4];
Array.prototype.unique = function() {
var result = [];
for (var i = 0 ; i < this.length; i++) {
var isNew = true;
for (var j = 0; j < result.length && isNew; j++) {
if (result[j] === this[i]){
isNew = false;
}
}
if(isNew) {
result.push(this[i]);
}
}
return result;
};
console.log(array.unique()); // [ 'a', '2', 1, 2, 3, 4 ]
注意,當(dāng)數(shù)組中存在多個(gè)NaN
元素的話牺弹,本方法并不適用浦马,因?yàn)?code>NaN不與任何值相等,甚至包括它本身张漂,只能用isNaN()
判斷晶默。好在這種情況在生產(chǎn)中遇到的并不多。
2航攒、利用JS對象來篩選重復(fù)元素
這個(gè)方法的效率比上面高磺陡,但是適用范圍不是很廣。思路還是構(gòu)建一個(gè)新數(shù)組,不過在判斷是否有重的時(shí)候币他,使用對象是否能訪問到這個(gè)屬性來判斷是否進(jìn)行push操作坞靶。如果能訪問到這個(gè)對象,那么說明該元素已經(jīng)被push過了蝴悉,就不再進(jìn)行push操作彰阴。
var array = ["a","a","2","2",1,3,4,4,4];
Array.prototype.unique2 = function() {
var result = [];
var ob = {}; // 新建一個(gè)空對象
var len = this.length;
for(var i = 0; i < len ; i++) {
if (!ob[this[i]]) { // 若對象中沒有這個(gè)屬性
result.push(this[i]);
ob[this[i]] = 1; // 在對象中添加這個(gè)屬性,并設(shè)置值為1(不能設(shè)置為0等假值拍冠,否則)
}
}
return result;
};
console.log(array.unique2()); //[ 'a', '2', 1, 3, 4 ]
需要注意的是尿这,由于javaScript中對象的屬性的類型其實(shí)都是string
,所以上述方法僅對只含string
的數(shù)組支持比較友好庆杜,因?yàn)槠渌臄?shù)據(jù)類型在被當(dāng)做對象屬性的時(shí)候射众,都會被轉(zhuǎn)為字符串,如下例晃财。
var array2 = [1,1,"1"];
console.log(array2.unique2()); // [ 1 ]
這個(gè)函數(shù)沒有返回我們期望的值[1,"1"]
叨橱,因?yàn)樵趯?code>number類的1
存為屬性的時(shí)候,javascript將它轉(zhuǎn)成了字符串形式断盛,因此罗洗,1
以及"1"
在這種去重方法里面被認(rèn)為是相等的。這種方法在這種情況下并不適用郑临。
3栖博、利用ES6的Set數(shù)據(jù)結(jié)構(gòu)
ES6的Set數(shù)據(jù)結(jié)構(gòu)有不能存在重復(fù)key的特性屑宠,利用這一特性厢洞,數(shù)組去重就簡單多了。關(guān)于Set的知識點(diǎn)這里典奉。
let array = ["a","a","2","2",1,3,4,4,4];
Array.prototype.unique3 = function() {
return Array.from(new Set(this));
};
console.log(array.unique3()); // [ 'a', '2', 1, 2, 3, 4 ]
可以看見躺翻,利用ES6的新特性解決這類問題會簡單很多,雖然目前不支持ES6的瀏覽器也挺多卫玖,但也要考慮歷史的進(jìn)程公你,再不濟(jì),我們還有 Babel 假瞬。