js去重的幾種方法:
1.使用indexOf()方法---[a.檢查當前數組是否存在;b.比較數組的下標---(借助新數組,原數組)]
2.for內外雙層循環
3.先排序后去重---不考慮原數組的順序時可以考慮使用
4.對象鍵值法去重(速度快,但占內存大,空間換時間)
- 方法一 使用indexOf()方法判斷當前數組的元素是否存在,不存在就存進新的數組,否則跳過。
注意indexOf方法是es5的新特性 不兼容ie8及以下的版本
var arr = [3,1,2,1,1,3,4,5,6,7];
console.log(arr);
function req1(arr){
var newarr = []; //新建臨時數組
for(var i = 0; i < arr.length; i++){
//如果當前數組的第i已經保存進了臨時數組,那么跳過,
//否則把當前項push到臨時數組里面
if (newarr.indexOf(arr[i]) == -1) newarr.push(arr[i]);
}
return newarr;
}
console.log(req1(arr)) //[3, 1, 2, 4, 5, 6, 7]
- //方法二 數組下標 通過indexOf方判斷當前元素在數組中的索引如果與循環的下標相等則添加到新數組中
//實現思路:如果當前數組的第i項在當前數組中第一次出現的位置不是i,那么表示第i項是重復的,忽略掉。否則存入結果數組。
//性能跟方法1差不多,
function rep2(arr) {
var newarr = [];
for (var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) == i) newarr.push(arr[i]);
}
return newarr;
}
console.log(rep2(arr)); //[3, 1, 2, 4, 5, 6, 7]
- //方法三 在原來的數組上 借助indexOf()方法判斷此元素在該數組中首次出現的位置下標與循環的下標不相等則刪除掉
function rep3(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) != i) {
arr.splice(i,1);//刪除數組元素后數組長度減1后面的元素前移
i--;//數組下標回退
}
}
return arr;
}
console.log(rep3(arr)); //[3, 1, 2, 4, 5, 6, 7]
- //方法四 常規方法 新舊數組都需要進行循環,因此效率比較低
var arr = ['d','b','c',1,2,3,'a','b']
// console.log(arr)
function rep4(arr) {
var newarr = [arr[0]] //這里構建一個newarr數組 且存放了第一個值 以便下面對比
for (var i= 1; i< arr.length; i++) {
var isrepeat = false
for (var j= 0; j< newarr.length; j++) { //循環兩個數組做對比
if(arr[i] == newarr[j]) {
isrepeat = true
break //這里判斷下循環arr時候跟newarr對比 相等就跳出 且給出標記 當前arr數組第幾個是出現重復的
}
}
if (!isrepeat) {
newarr.push(arr[i]) //這里 true標記的都是重復的 false都是可以添加的
}
}
return newarr //返回
}
console.log(rep4(arr)) //["a", "b", "c", 1, 2, 3]
- //方法五 排序后去重
//實現思路:給傳入數組排序,排序后相同值相鄰,然后遍歷時 就比較原數組的元素和新數組最后一個元素是否相同。
//缺點:改變了原數組的順序
// 將相同的值相鄰,然后遍歷去除重復值
var arr = ['e','a','b',1,2,3,'a','b'];
function rep5(array){
array.sort();
var newarr=[array[0]]; //構建一個newarr數組 存放原數組第一個元素
for(var i = 1; i < array.length; i++){
if( array[i] !== newarr[newarr.length-1])
{
newarr.push(array[i]);
}
}
return newarr;
}
console.log(rep5(arr)) //[1, 2, 3, "a", "b", "e"]
- //方法六 對象鍵值法去重(推薦使用)
//速度最快, 占空間最多(空間換時間)
//思路:新建一js對象以及新數組,遍歷傳入數組時,判斷值是否為js對象的鍵,不是的話給對象新增該鍵并放入新數組。
var arr = ['f', '0', '3', '2', 'd', 'd',0,2]
function rep6(arr) {
var newarr = [] //構建newarr 數組
var obj = {} //構建一個對象obj
for (var i= 0; i< arr.length; i++) {
if (!obj[arr[i]]) { //如果元素跟數組對比
newarr.push(arr[i])
obj[arr[i]] = 1 // 元素內容作為對象屬性,不為0就行
//將當前數組的這個屬性設置一個值表示對象中有了這個值
}
}
return newarr
}
console.log(rep6(arr)) //["f", "0", "3", "2", "d"]
//注意點:判斷是否為js對象鍵時,會自動對傳入的鍵執行“toString()”,JS 的鍵是不分類型的
//不同的鍵可能會被誤認為一樣,例如n[val]-- n[1]、n["1"];
//解決上述問題還是得調用“indexOf()”。如果要區分數字和字符串,就要保存類型
//理解:當遍歷到一個新值 val,問題中的代碼會檢查 val 是否在 obj 的鍵中,然后檢查 val 的類型是否在 val 鍵對應的值中,兩種皆否則認定這是一個非重復的值。
function rep6_1(array){
var obj = {}, newarr = [], len = array.length, val, type;
for (var i = 0; i < array.length; i++) {
val = array[i];
type = typeof val; //判斷val類型
//1.判斷val是否在obj的鍵中;2.判斷val的類型是否在val鍵對應的值中。找不到返回-1
if (!obj[val]) {
obj[val] = [type];
newarr.push(val);
} else if (obj[val].indexOf(type) < 0) {
//返回的結果是true 小于0是正確的
obj[val].push(type);
newarr.push(val);
}
}
return newarr;
}
console.log(rep6_1(arr)) //["f", "0", "3", "2", "d", 0, 2]
- //方法七 是四的優化
//實現思路:獲取沒重復的最右一值放入新數組。(檢測到有重復值時終止當前循環同時進入頂層循環的下一輪判斷)
//可以辨別0 和 “0” 比方法六的方法還優化
var arr = ['g', '0', '3', '2', 'd', 'd',0]
function rep7(array){
var r = [];
var len = array.length;
for(var i = 0;i < len; i++) {
for(var j = i + 1; j < len; j++){
if (array[i] === array[j]) j = ++i;
}
r.push(array[i]);
}
return r;
}
console.log(rep7(arr)) ////["g", "0", "3", "2", "d"]