面試官在「逗」你係列:數組去重你會幾種呀?

前言

數組去重是一個老生常談的話題,也是前端童鞋在面試時的一道高頻題。本文將深刻的探索數組去重的原理及實現,爲各位小夥伴提供多種能夠反手「調戲」面試官的解決方案。前端

話很少說,上去就來一梭子...

數組去重核心原理

價值100W的核心原理上來就給你了...,記得留言點贊鴨!
  1. 通常咱們都會建立臨時變量tmp,存儲不重複的元素(以數組元素存儲或對象的鍵來存儲);
  2. 遍歷待去重數組arr,依次判斷tmp中是否包含該元素;
  3. 若tmp中不存在該元素,則放入;不然跳過不處理。
基本上不管什麼樣的實現,其核心皆是如此(判斷是否已存在)。不行你就留言,我們能夠 battle一下

經典去重方案一:

設置tmp爲對象,對象的鍵存儲數組元素的值,最終返回對象的全部鍵。
function array_unique (arr) {
  if (arr.length === 0) {
    return arr
  }
  let tmp = {}
  let len = arr.length
  for (let i = 0; i < len; i++) {
    if (tmp[arr[i]] === undefined) {
      tmp[arr[i]] = i
    }
  }
  return Object.keys(tmp)
}

// 調用數組去重
let arr = [1, 2, 3, 1, 2]
let newArr = array_unique(arr)
console.log(newArr) // ['1', '2', '3']

若是你採用這種方式來回答面試官的話,你就陷入了他在心裏中早早設下的陷阱:面試

  1. 你這種方式能區分數字和字符串嗎?能區分undefined'undefined'嗎?
  2. 你如今返回的數據類型還和原有的數據類型一致嗎?

帶着面試官的疑問,咱們來看另一種經典去重方式。數組

經典去重方式二:

設置tmp爲數組,數組中存儲惟一的元素,最終返回tmp
function array_unique (arr) {
  let len = arr.length
  if (!len) {
    return []
  }
  let tmp = []
  for (let i = 0; i < len; i++) {
    // 判斷數組arr的元素是否在數組tmp中
    if (tmp.indexOf(arr[i]) === -1) {
      tmp.push(arr[i])
    }
  }
  return tmp
}
let arr = [1, 2, 3, '1', 2, undefined, undefined, 'undefined']
let newArr = array_unique(arr)
console.log(newArr) // [1, 2, 3, '1', undefined, 'undefined']

此刻,心裏是否竊喜!架構

But, 若是你這麼考慮,又陷入了面試官的另外一個陷阱:框架

  1. 你這方式能篩選NaN嗎?

好吧,面試官最大,再考慮!學習

數組去重方式三:

原理仍是同去重方式二,只不過咱們使用ES6的 includes替換 indexOf方法,

includes() 方法,判斷數組中是否包含某個元素,若是包含返回true,不然返回falsecode

就是這麼so easy!對象

function array_unique (arr) {
  let len = arr.length
  if (!len) {
    return []
  }
  let tmp = []
  for (let i = 0; i < len; i++) {
    // 判斷數組arr的元素是否在數組tmp中
    if (!tmp.includes(arr[i]) {
      tmp.push(arr[i])
    }
  }
  return tmp
}
let arr = [1, 2, 3, '1', 2, undefined, undefined,  'undefined', NaN, NaN]
let newArr = array_unique(arr)
console.log(newArr) // [1, 2, 3, '1', undefined, 'undefined', NaN]

此刻,你覺得就結束嗎?不,不可能!索引

面試官的坑已經在前面等你好久了:字符串

  1. 你的這個篩選方式能區分對象嗎?如{}、{a: 1}

有沒有想把本身的四十米大砍刀拿出來,neng屎面試官!(圖就不配了,本身腦補吧...)
然而,什麼都作不了,繼續想吧...

數組去重方式四:

原理同上,咱們要繼續換一個判斷數組是否包含某元素的方法: `findIndex

findIndex查詢數組是否包含某元素,若是存在返回元素的索引,不然返回-1。它比indexOf更加先進的地方在於能傳入callback,按約定方式查詢。

function array_unique (arr) {
  let len = arr.length
  if (!len) {
    return []
  }
  let tmp = []
  for (let i = 0; i < len; i++) {
    // 判斷數組arr的元素是否在數組tmp中
    if (tmp.findIndex((v) => JSON.stringify(v) === JSON.stringify(arr[i])) === -1) {
      tmp.push(arr[i])
    }
  }
  return tmp
}
let arr = [1, 2, 3, '1', 2, undefined, undefined,  'undefined', NaN, NaN, {}, {}, {a: 1}, {a: 1}]
let newArr = array_unique(arr)
console.log(newArr) // [1, 2, 3, '1', undefined, 'undefined', NaN, {}, {a: 1}]
終於成功啦!來來來,能夠瀟灑的問面試官,「您還有問題沒有?」

固然,主動挑釁面試官,是要承擔風險呦,有可能會由於你眨眼的時候,先眨了右眼被掛掉了...

判斷數組是否包含某元素的幾種方式:

給你們列個表格,好區分幾個方法的做用,

方法是否可檢測 null undefined NaN {} 備註
indexOf
includes
findIndex 需傳入特定的callback

小結

數組去重這道面試題,考察的知識點仍是很是多的。首先是對數組的經常使用方法要比較熟悉,還有其餘的如NaN與NaN不相等,{}與{}不相等等知識點,以及靈活多變的思惟邏輯。

固然,數組去重還有其餘的多種實現方式,歡迎各位小夥伴留言交流!

後記

以上就是胡哥今天給你們分享的內容,喜歡的小夥伴記得點贊收藏呦,關注胡哥有話說,學習前端不迷路,歡迎多多留言交流...

胡哥有話說,一個有技術,有情懷的胡哥!現任京東前端攻城獅一枚。

胡哥有話說,專一於大前端技術領域,分享前端系統架構,框架實現原理,最新最高效的技術實踐!

相關文章
相關標籤/搜索