JavaScript中數(shù)組去重的辦法總結(jié)
前言
你是否在面試的過程中被考到過給你一個數(shù)組讓你去掉重復(fù)項呢?當(dāng)時你的腦海里除了用Set實現(xiàn)之外,你還與面試官講了什么去重的方法呢?你能否封裝來一個可復(fù)用的數(shù)組去重api呢?依稀記得當(dāng)時我被問到這個問題的時候,我也沒回答出很多種解決辦法。那下面我來總結(jié)一下對于數(shù)組去重這道簡單的面試題時,我們可以回答的方法有什么吧。
數(shù)組去重
1. 不使用數(shù)組API方法
首先我來介紹一種不是用數(shù)組身上的API的去重解法,代碼如下:
var array = ['1', 1, '1', '1', '2', 2] function unique(array) { let res = [] for(let i = 0; i < array.length; i++){ for( var j = 0; j < res.length; j++){ if(array[i] === res[j]){ break; } } if(j === res.length){ res.push(array[i]) } } return res } console.log(unique(array)); // [ '1', 1, '2', 2 ]
既然不使用數(shù)組自帶的API方法,那我們首先考慮的就是用雙重for循環(huán)了,如上述代碼:
- 我們準(zhǔn)備了一個空的結(jié)果數(shù)組
- 我們對需要去重的數(shù)組進(jìn)行循環(huán)
- 在第一層數(shù)據(jù)中再套一層循環(huán),根據(jù)下標(biāo)判斷結(jié)果數(shù)組內(nèi)是否有重復(fù)項。
我們調(diào)用該方法,打印結(jié)構(gòu)如上述代碼的注解處,成功的實現(xiàn)了對數(shù)組的去重。
2. 使用 indexOf
既然有不使用數(shù)組API的,那就肯定有使用數(shù)組API的,下面看我使用indexOf完成數(shù)組的去重,代碼如下:
var array = ['1', 1, '1', '1', '2', 2] function unique(array) { let res = [] for (let i = 0; i < array.length; i++) { if (res.indexOf(array[i]) === -1) { // 返回找到的第一個值得下標(biāo) res.push(array[i]) } } return res } console.log(unique(array))// [ '1', 1, '2', 2 ]
如上述代碼, 我們巧妙了使用了indexOf查找結(jié)果數(shù)組中是否已經(jīng)存在,如果不存在才向結(jié)果數(shù)組中添加,實現(xiàn)了數(shù)組去重。
在上述代碼的基礎(chǔ)上,我們還可以轉(zhuǎn)變一下,將for循環(huán)內(nèi)的語句改為:
if (array.indexOf((array[i])) == array.lastIndexOf(array[i])) { i++ } else { array.splice(array.lastIndexOf(array[i]), 1) }
不新增其他變量,直接通過indexOf和lastIndexOf判斷該值是否在原數(shù)組內(nèi)為唯一值,從而直接修改原數(shù)組,實現(xiàn)數(shù)組的去重。
3. 使用 sort
對于數(shù)組去重,我們除了通過下標(biāo)找出是否有重復(fù)項之外,我們還可以先排序,然后在判斷前后項是否相同來實現(xiàn)去重,代碼如下:
var ?array = [1, 3, 5, 4, 2, 1, 2, 4, 4, 4] function unique(array) { let res = [] let sortedArray = array.concat().sort() //concat() 返回新的數(shù)組 let seen; for (let i = 0; i < sortedArray.length; i++) { if (!i || seen !== sortedArray[i]) { res.push(sortedArray[i]) } seen = sortedArray[i] } return res } console.log(unique(array)); // [ 1, 2, 3, 4, 5 ]
如上述代碼, 我們先獲取一個排好序的新數(shù)組,再對新數(shù)組進(jìn)行循環(huán),判斷保存前一個值的seen與當(dāng)前值是否相同來實現(xiàn)數(shù)組去重。
溫馨小提示: 由于數(shù)組的排序方法不能區(qū)分?jǐn)?shù)組和字符串,所以想要使用此方法必須要保證數(shù)組的值的類型相同,不然會出bug
4. 使用 filter
既然都用到了sort排序了,那我直接抬出ES6數(shù)組新增的filter過濾器API也不過分吧,代碼如下:
var array = ['1', 1, '1', '1', '2', 2] function unique(array) { let res = array.filter((item, index, array) => { return array.indexOf(item) === index }) return res } console.log(unique(array)); // [ '1', 1, '2', 2 ]
如上述代碼,filter直接使用array.indexOf(item) === index
作為過濾條件返回出一個新的數(shù)組,實現(xiàn)數(shù)組去重。
如上述代碼,我們結(jié)合了 indexOf方法作為過濾條件,那我們也可以結(jié)合一下sort方法吧,直接使用一行代碼就解決了數(shù)組的去重。代碼如下:
function unique(array) { return array.concat().sort().filter((item, index, array) => !index || item !== array[item - 1]) } console.log(unique(array)); // [ '1', 1, '2', 2 ]
5. 使用Set、Map、或者對象
除了上述的通過數(shù)組API和不使用數(shù)組API的方法外,我們還能想到的就是借助對象來實現(xiàn)數(shù)組的去重。使用Set數(shù)據(jù)結(jié)構(gòu)是我們最容易想到的辦法,使用Map與對象方法的相似,都是以數(shù)組的值作為key,再將所有的可以取出來組成一個數(shù)組。 我就不給小伙伴們演示代碼了,感興趣的小伙伴可以自己動手試試。
(對于對象的key只能為字符串這個問題,我們可以換個思路,將下標(biāo)存為key,值存為value,判斷不同key的值相不相同來實現(xiàn)數(shù)組去重。我們還可以在存key時加上其類型,然后進(jìn)行一次轉(zhuǎn)換。)
自己封裝一個去重API
在介紹上述數(shù)組去重的方法后,我們再來總結(jié)一下,將其融合成一個有復(fù)用性,而且還可以適用不同情況的API方法。
我來介紹一下如下我封裝的一個數(shù)組去重的API方法,
- 該方法可接受三個參數(shù),第一個參數(shù)為需要去重的數(shù)組,第二個參數(shù)為該數(shù)組是否為排好序的數(shù)組,第三個參數(shù)為一個回調(diào)函數(shù)
- 該回調(diào)函數(shù)也有三個參數(shù),分別為值,下標(biāo),需要去重數(shù)組。該回調(diào)函數(shù)的作用是方便用戶對數(shù)組進(jìn)行一些額外的處理(例如將大寫轉(zhuǎn)為小寫)
- 第二,三參數(shù)可不傳遞。
var array = [1, 2, '1', 'a', 'A', 2, 1] var array2 = [1, 1, '1', 2, 2] function uniq(array, isSorted, iteratee) { let seen = [] let res = [] for(let i = 0; i < array.length; i++){ let computed = iteratee ? iteratee(array[i], i,array) : array[i] if(isSorted) { if(!i || seen !== array[i]){ res.push(array[i]) } seen = array[i] }else if(iteratee) { if(seen.indexOf(computed) === -1){ seen.push(computed) res.push(computed) } } else { if(res.indexOf(array[i]) === -1) { res.push(array[i]) } } } return res } let result = uniq(array, false, function(item, index, arr){ return typeof item == 'string' ? item.toLowerCase() : item }) console.log(result); // [ 1, 2, '1', 'a' ] console.log(uniq(array2, true)); // [ 1, 2 ]
總結(jié)
對于數(shù)組的去重,當(dāng)我們能在面試中說到這個多方法的話,這道面試題也就過了,雖然這道面試不難,但如果我們想要想到這個多方法的話,還是需要許多知識儲備的。
以上就是JavaScript中數(shù)組去重的辦法總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript數(shù)組去重的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
從數(shù)組中隨機取x條不重復(fù)數(shù)據(jù)的JS代碼
這篇文章主要介紹了從數(shù)組中隨機取x條不重復(fù)數(shù)據(jù)的JS代碼,有需要的朋友可以參考一下2013-12-12JavaScript Generator函數(shù)使用分析
生成器Generator是JavaScript ES6引入的特性,它讓我們可以分段執(zhí)行一個函數(shù)。但是在談?wù)撋善鳎℅enerator)之前,我們要先了解迭代器Iterator2022-10-10JavaScript中數(shù)組去重的辦法總結(jié)
你是否在面試的過程中被考到過給你一個數(shù)組讓你去掉重復(fù)項呢,下面小編就來總結(jié)一下對于數(shù)組去重這道簡單的面試題時,我們可以回答的方法有什么吧2023-06-06js實現(xiàn)當(dāng)復(fù)選框選擇匿名登錄時隱藏登錄框效果
這篇文章主要介紹了js實現(xiàn)當(dāng)復(fù)選框選擇匿名登錄時隱藏登錄框效果,實例分析了javascript動態(tài)操作頁面元素樣式的相關(guān)技巧,非常簡單實用,需要的朋友可以參考下2015-08-08