前言
陣列去重是一個老生常談的話題,也是前端童鞋在面試時的一道高頻題,本文將深入的探索陣列去重的原理及實作,為各位小伙伴提供多種可以反手“調戲”面試官的解決方案,
話不多說,上去就來一梭子...
陣列去重核心原理
價值100W的核心原理上來就給你了...,記得留言點贊鴨!
- 一般我們都會創建臨時變數tmp,存盤不重復的元素(以陣列元素存盤或物件的鍵來存盤);
- 遍歷待去重陣列arr,依次判斷tmp中是否包含該元素;
- 若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']
如果你采用這種方式來回答面試官的話,你就陷入了他在內心中早早設下的陷阱:
你這種方式能區分數字和字串嗎?能區分
undefined和'undefined'嗎?你現在回傳的資料型別還和原有的資料型別一致嗎?
帶著面試官的疑問,我們來看另外一種經典去重方式,
經典去重方式二:
設定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, 如果你這么考慮,又陷入了面試官的另一個陷阱:
- 你這方式能篩選NaN嗎?
好吧,面試官最大,再考慮!
陣列去重方式三:
原理還是同去重方式二,只不過我們使用ES6的
includes替換indexOf方法,includes() 方法,判斷陣列中是否包含某個元素,如果包含回傳true,否則回傳false
就是這么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]
此刻,你以為就結束嗎?不,不可能!
面試官的坑已經在前面等你很久了:
- 你的這個篩選方式能區分物件嗎?如{}、{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不相等,{}與{}不相等等知識點,以及靈活多變的思維邏輯,
當然,陣列去重還有其他的多種實作方式,歡迎各位小伙伴留言交流!
后記
以上就是胡哥今天給大家分享的內容,喜歡的小伙伴記得點贊、收藏呦,關注胡哥有話說,學習前端不迷路,歡迎多多留言交流...
胡哥有話說,一個有技術,有情懷的胡哥!現任京東前端攻城獅一枚,
胡哥有話說,專注于大前端技術領域,分享前端系統架構,框架實作原理,最新最高效的技術實踐!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/90155.html
標籤:JavaScript
