JavaScript數(shù)組去重7種方法解析(常用方法)
一、核心解題邏輯
所有去重方法的本質(zhì)的是:識別并保留首次出現(xiàn)的元素,剔除重復(fù)元素。不同方法的核心差異在于「判斷元素是否重復(fù)的方式」「兼容性」和「執(zhí)行效率」,面試中需根據(jù)場景靈活選擇。
滿分答題框架(面試必備):
基礎(chǔ)類型去重:優(yōu)先用 Set(簡潔高效,支持 NaN);
對象數(shù)組去重:用 Map+指定字段(按唯一鍵去重,適配復(fù)雜場景);
兼容舊瀏覽器:用優(yōu)化后的對象鍵值法或 indexOf+遍歷;
性能優(yōu)先:避開 O(n²) 方法,選擇 O(n) 級別的 Set/Map/對象鍵值法。
二、基礎(chǔ)類型數(shù)組去重(常用方法)
基礎(chǔ)類型指 Number、String、Boolean、NaN 等,以下方法針對這類場景展開。
1. Set 方法(推薦首選)
核心思路
利用 ES6 Set 結(jié)構(gòu)「值唯一、不允許重復(fù)」的特性,自動過濾重復(fù)元素。Set 內(nèi)部采用 SameValueZero 算法,可正確識別 NaN 為重復(fù)值(解決 indexOf 無法匹配 NaN 的痛點)。
代碼實現(xiàn)(極簡版+封裝版)

優(yōu)缺點與復(fù)雜度
? 優(yōu)點:代碼極簡、執(zhí)行效率高(時間復(fù)雜度 O(n))、支持 NaN 去重;
? 缺點:僅兼容 ES6+(IE 瀏覽器不支持),無法處理對象數(shù)組(對象引用不同視為不同元素);
2. indexOf + 遍歷(基礎(chǔ)樸素版)
核心思路
遍歷原數(shù)組,用 indexOf() 判斷當(dāng)前元素是否已存在于結(jié)果數(shù)組中(返回 -1 表示不存在),不存在則加入結(jié)果數(shù)組。
代碼實現(xiàn)

優(yōu)缺點與復(fù)雜度
? 優(yōu)點:兼容所有瀏覽器(包括 IE)、邏輯簡單易理解;
? 缺點:效率低(時間復(fù)雜度 O(n²))、無法處理 NaN 重復(fù);
3. includes + forEach(改進版,支持 NaN)
核心思路
用 includes() 替代 indexOf() 判斷元素是否存在,includes() 同樣采用 SameValueZero 算法,可正確識別 NaN。
代碼實現(xiàn)

優(yōu)缺點與復(fù)雜度
? 優(yōu)點:支持 NaN 去重、邏輯清晰;
? 缺點:效率低(O(n²))、兼容 ES7+(比 Set 兼容性稍差);
4. filter + indexOf(函數(shù)式寫法)
核心思路
用 filter() 過濾數(shù)組,僅保留「元素第一次出現(xiàn)的索引 === 當(dāng)前遍歷索引」的元素(重復(fù)元素的 indexOf 結(jié)果小于當(dāng)前索引)。
代碼實現(xiàn)

優(yōu)缺點
? 優(yōu)點:函數(shù)式編程風(fēng)格、代碼簡潔;
? 缺點:無法處理 NaN、效率 O(n²);
適用場景:小數(shù)據(jù)量、不需要處理 NaN 的簡單場景。
5. 對象鍵值法(兼容舊瀏覽器,需避坑)
核心思路
利用「對象鍵名唯一」的特性,將數(shù)組元素作為對象鍵名存儲,避免重復(fù)。需注意對象鍵名會自動轉(zhuǎn)為字符串,存在類型轉(zhuǎn)換坑。
基礎(chǔ)版(存在坑點)

優(yōu)化版(解決類型轉(zhuǎn)換坑)
通過「類型+值」拼接鍵名(如 `number_1`、`string_1`),區(qū)分不同類型的相同值。

優(yōu)缺點與復(fù)雜度
? 優(yōu)點:兼容舊瀏覽器(IE6+)、效率 O(n)、支持 NaN 去重;
? 缺點:基礎(chǔ)版存在類型轉(zhuǎn)換坑,優(yōu)化版代碼稍復(fù)雜;
三、對象數(shù)組去重(進階場景)
實際開發(fā)中對象數(shù)組去重更常見(如按 id 去重列表數(shù)據(jù)),核心是按「唯一字段」過濾,推薦用 Map 實現(xiàn)。
Map + 字段去重(推薦)
核心思路
用 Map 存儲已出現(xiàn)的字段值,遍歷數(shù)組時判斷字段值是否存在于 Map 中,不存在則存入 Map 并保留當(dāng)前元素。Map 支持任意類型鍵名,比對象更靈活。
代碼實現(xiàn)

優(yōu)缺點與復(fù)雜度
? 優(yōu)點:效率高(O(n))、靈活適配任意唯一字段、支持復(fù)雜類型鍵名;
? 缺點:兼容 ES6+;
適用場景:項目開發(fā)中對象數(shù)組去重(如表格數(shù)據(jù)、接口返回列表)。
四、關(guān)鍵坑點與注意事項
1. NaN 的匹配問題
indexOf/filter+indexOf:基于 === 匹配,NaN === NaN 為 false,無法去重 NaN;
Set/includes/Map:基于 SameValueZero 算法,視為 NaN 相等,可正確去重。
2. 類型轉(zhuǎn)換坑
對象鍵值法基礎(chǔ)版會將鍵名轉(zhuǎn)為字符串,導(dǎo)致 1 和 '1'、true 和 'true' 被視為同一元素,需通過「類型+值」拼接優(yōu)化。
3. 原數(shù)組修改問題
部分方法(如雙重 for 循環(huán)+splice)會直接修改原數(shù)組,開發(fā)中建議返回新數(shù)組(如用 filter、擴展運算符拷貝),避免副作用。
五、性能對比與場景選擇
方法 | 時間復(fù)雜度 | 兼容版本 | 適用場景 |
|---|---|---|---|
Set | O(n) | ES6+ | 基礎(chǔ)類型、現(xiàn)代項目、性能優(yōu)先 |
Map+字段 | O(n) | ES6+ | 對象數(shù)組、按唯一字段去重 |
優(yōu)化對象鍵值 | O(n) | IE6+ | 舊瀏覽器、基礎(chǔ)類型 |
indexOf/includes/filter | O(n²) | IE8+/ES7+ | 小數(shù)據(jù)量、簡單場景 |
六、總結(jié)
1. 高頻考點:Set 方法(代碼極簡,必寫)、indexOf 與 includes 的區(qū)別(NaN 處理)、對象數(shù)組去重(Map+字段);
2. 避坑要點:NaN 匹配規(guī)則、對象鍵值的類型轉(zhuǎn)換坑、原數(shù)組修改副作用;
3. 性能優(yōu)化:大數(shù)據(jù)量優(yōu)先選 O(n) 方法(Set/Map/優(yōu)化對象鍵值),避開 O(n²) 方法;
4. 兼容性回答:現(xiàn)代項目用 Set/Map,需兼容 IE 則用優(yōu)化對象鍵值法或 indexOf+遍歷。
到此這篇關(guān)于JavaScript數(shù)組去重7種方法解析的文章就介紹到這了,更多相關(guān)JS數(shù)組去重內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ES5 模擬 ES6 的 Symbol 實現(xiàn)私有成員功能示例
這篇文章主要介紹了ES5 模擬 ES6 的 Symbol 實現(xiàn)私有成員功能,結(jié)合實例形式分析了ES5 模擬 ES6 的 Symbol 實現(xiàn)私有成員功能相關(guān)原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下2020-05-05
js中offset,client , scroll 三大元素知識點總結(jié)
在本篇文章里小編給大家整理了關(guān)于js 元素offset,client , scroll 三大系列總結(jié),有需要的朋友們可以學(xué)習(xí)下。2019-09-09

