案例分析:
隨機生成20個十以內的數字。
隨機生成10以內數字
let arr = Array.from({length:20},=>Math.random()*10|0); console.log(arr); //輸出結果: [5,4,7,0,0,0,8,0,2,9,3,0,0,1,5,9,2,8,6,0]
思路:
雙層循環,外層循環元素,內層循環時比較值
值相同時,則刪去這個值
利用splice直接在原數組進行操作
Array.prototype.distinct = function (){ var arr = this, i, j, len = arr.length; for(i = 0; i < len; i++){ for(j = i + 1; j < len; j++){ if(arr[i] == arr[j]){ arr.splice(j,1); len--; j--; } } } return arr; }; var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,]; var b = a.distinct(); console.log(b.toString()); //1,2,3,4,5,6,56
注意:刪除相同值時,數組長度相應減一。
但是,我們要注意的是,此種方法會改變原數組的值,也就是說,我們改變了arr的結果。如果不想改變原數組改怎么辦呢?
不改變原數組
Array.prototype.distinct = function(){ var arr = this, result = [], i, j, len = arr.length; for(i = 0; i < len; i++){ for(j = i + 1; j < len; j++){ if(arr[i] === arr[j]){ j = ++i; } } result.push(arr[i]); } return result; } var arra = [1,2,3,4,4,1,1,2,1,1,1]; arra.distinct()
此種方法,先創建一個空數組,然后利用雙層循環,符合的,push進result數組中,若遇到相同值,則直接跳過,不再進行push操作。這樣,我們就避免了對原數組的操作。
這種方法解決了操作原數組的問題,但是,如果數組的值特別大怎么辦?比如說,數組arr有10000個值,找到第一項后,比較數組后面的值,那我們需要比較9999次,找到第二項,需要比較9998次。但是,我們已經確定了,我們的結果集中,就10個數,這樣顯然不是我們想要的,怎么辦呢?
為了提升性能,我們可以從結果集中進行比較。
indexOf的使用
let rs = []; for(let i=0;i<arr.length;i++){ if(rs.indexOf arr[i] === -1){ rs.push(arr[i]) } }; console.log(rs)
通過indexOf方法,如果得到的值為-1,則確定數組中不存在該值,這樣,我們就把arr[i],push到數組中。這樣我們就得到了去重后的數組。
既然我們想到了indexOf方法,那我們是不是還能有更加簡便的方法來使數組去重呢?
仔細想想,我們就會想到,數組的filter方法。
數組的filter方法
console.log(arr.filter(function(element,index,self){ return self.indexOf(element) === index; }));
element是數組的每個值,index是數組的索引,self是數組本身。
當使用indexOf方法時,如果數組的每項的indexOf方法得到的值與數組索引相同,則證明此值第一次出現,如果數組的索引與index的值不相同,則證明不是第一次出現。
前面我們介紹的這些方法,都是使用數組本身的方法。其實在js中,還有一個特殊的東西,叫做對象。
對象去重法
var o={}; var new_arr=[]; for(var i=0;i<arr.length;i++){ var k=arr[i]; if(!o[k]){ o[k]=true; new_arr.push(k); } } console.log(new_arr)
這種方法利用到,對象的屬性唯一行,來進行判斷。
為什么要用到這種方法呢?其實前面的方法,都用到了雙層循環,indexOf也不例外,但是利用對象的key來做判斷時,我們只用到了一次循環,這樣就會大大增加運行的性能,利用對象去重也是這些方法中運行速度最快的一種。
前面介紹到的這些種方法,都是ES3,ES5中用到的方法,接下來我們介紹一下利用ES6來進行數組去重的方法。
在本文的開頭,我們創建隨機數組的時候,用到了 Array.from()方法,在ES6中新增了from方法。接下來我們借助from方法和一些其他的方法來把數組進行去重。
form方法
let rs = Array.from(arr); //得到與當前一樣的數組
let rs= Array.from(new Set(arr)); // 利用ES6的Set方法進行去重。
console.log([...new Set(arr)]); //這種方法只用到了13個字符,也是數組去重最方便的方法。
總結:
數組去重在我們日常的開發中用到的比較少,但是我們要理解其中的邏輯,以便於我們更好的進行其他的開發任務。