JS數組去重的實現

其實數組去重的實現就分爲兩大類

  • 利用語法自身鍵不可重複性
  • 利用循環(遞歸)和數組方法使用不同的api來處理。

注意⚠️:下列封裝成方法的要在函數開始增加類型檢測,爲了讓去重的實現代碼更加簡單易懂,封裝時我會省略類型檢測

function noRepeat(){  
    if (!Array.isArray(arr)) {
    console.log('type error!')
    return
  }
  // XXX執行代碼
}

利用鍵不可重複性

Set

原理:利用set存儲的數據沒有重複,結果爲對象,需要再轉換成數組

// 方法一
var arr = [1,1,2,1,3,4,5];
var set = new Set(arr);
console.log(Array.from(set))
// 方法二
[...new Set(arr)];

利用對象的屬性

原理:利用對象的屬性唯一(速度快,佔空間多,用空間來換時間)

var res = [];
var obj = {};
for(var i=0; i<arr.length; i++){
  if(!obj[arr[i]] ){
    obj[arr[i]] = 1;
    res.push(arr[i]);
  }
}

Map

原理:利用map對象不重複,思路和對象屬性一致。

function arrayNonRepeatfy(arr) {
  let map = new Map();
  let array = new Array();  // 數組用於返回結果
  for (let i = 0; i < arr.length; i++) {
    if(map .has(arr[i])) {  // 如果有該key值
      map .set(arr[i], true); 
    } else { 
      map .set(arr[i], false);   // 如果沒有該key值
      array .push(arr[i]);
    }
  } 
  return array ;
}

利用數組下標不能重複(僅適用純數字數組)

原理:利用數組下標不能重複。

function norepeat(arr){
  var newArr = [];
  var arrs = [];
  for(var i=0;i<arr.length;i++){
    var a = arr[i];
    newArr[a] = 1;
  }
  for(var i in newArr){
    arrs[arrs.length] = i;
    console.log(i);
  }
}

利用循環(遞歸)和數組方法使用不同的api

indexOf()

原理:利用indexOf檢測新數組是否有當前元素,沒有則添加。

方式一 檢測新數組是否有當前元素
function norepeat(arr){
  var newarr = [];
  for(var i in arr) {
      if(newarr.indexOf(arr[i]) == -1){
          newarr.push(arr[i]);
      }
  }
  return newarr;
}

方式二 檢測當前元素第一次出現的位置和當前位置是否相等,相等則添加
function norepeat(arr){
  var newarr = [arr[0]];  //默認加入第一個數  因爲第一個數沒比較的必要
    for(var i =1;i<arr.length;i++){
        if(arr.indexOf(arr[i])==i){
            newarr.push(arr[i])
        }
    }
  return newarr;
}

方式三 filter和indexOf
function unique(arr) {
  return arr.filter(function(item, index, arr) {
    //當前元素,在原始數組中的第一個索引==當前索引值,否則返回當前元素
    return arr.indexOf(item, 0) === index;
  });
}

includes()

原理:利用includes檢測新數組中是否含有當前元素,沒有則添加

方式一 利用普通for循環和includes
function norepeat(arr) {
  var newarr =[];
  for(var i = 0; i < arr.length; i++) {
   if(!newarr.includes(arr[i])) { //includes 檢測數組是否有某個值
      newarr.push(arr[i]);
    }
  }
  return array
}

方式二 利用reduce和includes
function norepeat(arr){
    return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}

注意⚠️:indexOf和includes均可以和for循環,reduce配合使用

sort()

原理:先利用sort排序再比較相鄰的是否相等

// 方法一 檢測相鄰相等則添加到新數組
function norepeat(arr) {
  arr = arr.sort()
  var arrry= [arr[0]];
  for(var i = 1; i < arr.length; i++) {
    if(arr[i] !== arr[i-1]) {
      arrry.push(arr[i]);
    }
  }
  return arrry;
}

// 方式二 在原數組上檢測,相鄰元素相同則刪除
function norepeat(arr) {
  arr.sort(function (a, b) { return a - b; });
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] == arr[i + 1]) {
      arr.splice(i, 1);
      i--;
    }
  }
  return arr;
}

遞歸

原理:借用遞歸比較 index和index-1位是否相同,相同則刪除

function noRepeat(arr) {
  // 獲取長度
  var len = arr.length;
  //對數組進行排序才能方便比較
  arr.sort(function (a, b) {
   return a - b;
  })
  // 用遞歸的方法進行去重
  function loop(index) {
    if (index >= 1) {
      if (arr[index] === arr[index - 1]) {
        arr.splice(index, 1);
      }
      loop(index - 1); //遞歸loop函數進行去重
    }
  }
  loop(len - 1);
  return arr;
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章