1. 程式人生 > >面試官在“逗”你係列:陣列去重你會幾種呀?

面試官在“逗”你係列:陣列去重你會幾種呀?

## 前言 陣列去重是一個老生常談的話題,也是前端童鞋在面試時的一道高頻題。本文將深入的探索陣列去重的原理及實現,為各位小夥伴提供```多種```可以```反手“調戲”```面試官的解決方案。 > 話不多說,上去就來一梭子... ## 陣列去重核心原理 > 價值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,否則返回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] ``` > 此刻,你以為就結束嗎?不,不可能! > > 面試官的坑已經在前面等你很久了: > > 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不相等,{}與{}不相等等知識點,以及靈活多變的思維邏輯。 > 當然,陣列去重還有其他的多種實現方式,歡迎各位小夥伴留言交流! ## 後記 以上就是胡哥今天給大家分享的內容,喜歡的小夥伴記得```點贊```、```收藏```呦,關注胡哥有話說,學習前端不迷路,歡迎多多留言交流... > 胡哥有話說,一個有技術,有情懷的胡哥!現任京東前端攻城獅一枚。 > > 胡哥有話說,專注於大前端技術領域,分享前端系統架構,框架實現原理,最新最高效的技術