數組去重,這是一個面試常常會碰見的問題,網上講數組去重的文章也是特別的多,可是咱們依舊來說講數組去重,這篇文章比較適合於接觸過一段時間的JavaScript的初學者,但願這篇文章能給初學者帶來一些幫助。javascript
function unique(arr) {
var result = []; //結果數組
for(var i = 0; i < arr.length; i++)
{
//若是在結果數組result中沒有找到arr[i],則把arr[i]壓入結果數組result中
if (result.indexOf(arr[i]) == -1) result.push(arr[i]);
}
return result;
}
Array.prototype.unique = function() {
var result = [this[0]]; //結果數組
for(var i = 1; i < this.length; i++) //從第二項開始遍歷
{
//若是調用unique()方法的數組的第i項在數組中第一次出現的位置是i,
//那麼表示第i項是不重複的,則存入結果數組
if (this.indexOf(this[i]) == i) result.push(this[i]);
}
return result;
}
解釋
方法一和方法二,看第一眼,可能沒什麼,等你把兩個方法弄明白,才發現區別真的不大,就像是同一我的只是換了件衣服而已。
好吧,咱們看看這我的是誰,要說這我的是誰,重點在於for循環、indexOf( )方法和push( )方法。
for循環就沒必要多作解釋了,既然接觸過JavaScript必定是明白的
在Array 對象中
indexOf( )方法搜索數組中的元素,並返回它首次出現的位置,若是沒找到則返回 -1。
在String 對象中
indexOf( ) 方法可返回某個指定的字符串值在字符串中首次出現的位置,若是沒找到則返回 -1。
注意:
JavaScript中的Array對象 和 String對象都是具備indexOf( )方法的,並且用法是同樣的。
對於indexOf( )不是很理解的朋友點這裏 html
push( ) 方法可向數組的末尾添加一個或多個元素,並返回新的長度。
push( )方法是Array對象中的方法,String對象中沒有。
對於push( )不是很理解的朋友點這裏 java
那衣服是什麼呢?咱們繼續說,方法一,是定義了一個函數unique,傳入的參數沒有限制,也就是說,不論是誰均可以用這個方法,看圖
數組能用這個方法,字符串也能用這個方法。
而方法二是在Array對象中添加了一個unique( )方法,這樣的話,就只能是數組才能用這個方法了,看圖
用字符串去調用這個方法,報錯了,由於字符串沒有這個方法,只有數組有,這樣就多了一種限制。 web
function unique3(arr){
//遍歷arr,同時建立結果數組result
for(var i=0,result=[];i<arr.length;i++){
//遍歷結果數組result
for(var j=0;j<result.length;j++){
//若是result中有一個元素等於arr[i],就退出循環
//說明arr[i],是一個重複的元素
if(result[j]===arr[i]){break;}
}//遍歷結束
//若是j等於result的length,就把arr[i],壓入數組result
//j等於result的length,說明遍歷到了最後,也就是沒有找到相同的元素
if(j===result.length){
result[result.length]=arr[i];
}
}
return result;//返回result
}
Array.prototype.unique4 = function(){
//建立結果數組,值爲調用unique4()方法的數組的第一個元素
var result = [this[0]];
//遍歷 調用unique4方法的數組
for(var i = 1; i < this.length; i++){
//聲明一個變量 repeat,判斷元素是否是重複
var repeat = false;
//遍歷結果數組 result
for(var j = 0; j < result.length; j++){
//若是結果數組result中的一個元素,等於,調用unique4()方法的數組的其中一個元素,repeat值爲true,跳出循環
//也就是結果數組result中的這個元素和調用unique4()方法的數組中的元素重複了
if(this[i] === result[j]){
repeat = true;
break;
}
}
//若是結果數組result中的一個元素,不等於,調用unique4()方法的數組的其中一個元素,repeat值爲false,把元素添加到結果數組
//也就是結果數組result中的這個元素和調用unique4()方法的數組中的元素不重複
if(!repeat){
result.push(this[i]);
}
}
// 返回結果數組result
return result;
}
解釋
我相信,你已經看出來了,方法三和方法四的區別也不大,能明白其中一個,另外的也同樣!這兩個方法,看上去代碼挺多,你能夠去掉註釋看看,其實也很少,主要的就是兩層for循環罷了,而內層的for循環實際上是實現了一下indexOf( )的功能。 面試
function unique5(arr){
// 建立結果數組
var result = [];
//建立hash對象,用來代替indexOf
var hash = {};
for(var i = 0; i < arr.length; i++){
//key就是數組元素的類型+數組元素,用來區分number和"number"
var key = typeof(arr[i]) + arr[i];
//若是hash對象中的key屬性值不等於1(說明hash對象中不存在key屬性),就把arr[i]壓入結果數組result,同時設置hash的key屬性值爲1
if(hash[key]!==1){
result.push(arr[i]);
hash[key] = 1;
}
}
return result;
}
Array.prototype.unique6=function(){
// 建立結果數組
var result = [];
//建立hash對象,用來代替indexOf
var hash = {};
for(var i=0;i<this.length;i++){
// hash[this[i]] ,這是看 hash 中是否有 this[i] 這個屬性,若是有,該屬性值就+1,這個值就是出現的次數
if(hash[this[i]]){
hash[this[i]]++;
}
//若是,hash中沒有this[i]屬性,則將this[i]壓入結果數組result,同時給這個屬性,賦值爲1
else{
result.push(this[i]);
hash[this[i]]=1;
}
}
//最後返回了一個對象,包括告終果數組,和帶次數的hash對象
return {result,hash};
}
解釋
好吧,方法五和方法六差很少,核心思想和前面的幾種方法同樣,可是仍是有一些不一樣的,方法五中寫var key = typeof(arr[i]) + arr[i];
這句是由於在 JavaScript 裏,對象的鍵只能是字符串,因此爲了區分數組中的數字,和能轉爲數字的字符串,就須要這句了,而方法六就不能區分了,看圖
數組
Array.prototype.unique7 = function(){
//先排序
this.sort();
//建立結果數組
var result = [this[0]];
/* 遍歷 調用unique7()方法的數組 若是該數組中的第i項, 不等於結果數組result中的最後一項,就把第i項,壓入結果數組 */
for(var i = 1; i < this.length; i++){
if(this[i] !== result[result.length - 1]){
result.push(this[i]);
}
}
return result;
}
解釋
此次終因而不同了,思路已經換了,此次須要先把數組排序,這點很重要,排序以後,再進行比較,比較的是,調用方法的數組和結果數組,其實也就是在比較調用方法的數組中的,第i項和第i-1項,若是相等,就什麼都不作,不相等就把第i項壓入結果數組。 svg
這裏這些方法我比較推薦用 方法五 和 方法七。
若是你認同這七種方法,能夠算是解決數組去重問題的方法,那麼我相信,你能夠寫出更多的方法來,若是你以爲這裏不少的方法的思路是同樣的,只能算是兩種方法,我也贊成。
若是你以爲這些方法太麻煩,看這裏,
JavaScript數組去重—ES6的兩種方式
這篇文章中的方法可能更適合你哦!
若是你還有什麼更有趣方法,也歡迎分享出來。 函數