JavaScript數(shù)組去重的六種方式
一、最樸素的方法去重:雙重for循環(huán)
一想到去重,第一個就想到了雙重for循環(huán),遍歷兩層比較一下就好了,不過要注意的是,用數(shù)組的splice
刪除重復(fù)項后,需要將第二層循環(huán)的索引減1,不然會出現(xiàn)數(shù)組塌陷的問題。
function unique(arr) { for (let i = 0; i < arr.length; i++) { for (let j = i + 1; j < arr.length; j++) { if (arr[i] === arr[j]) { arr.splice(j, 1); j--; // 注意:由于刪除了元素,需要將 j 減一,以避免漏掉第j項的檢查 } } } return arr; } const arr = [1,1,2,2,3,4,4,5,5,6]; console.log(unique(arr)); // 輸出:[ 1, 2, 3, 4, 5, 6 ]
二、最省時間的去重:obj/Map存儲 + for循環(huán)
由于對象Object
的key
值唯一,所以我們可以利用這個特性進行去重。核心思路就是用對象
或者Map
將遍歷過的項作為key
存儲到對象或者Map
中,如果遇到已經(jīng)存在的key
,則說明出現(xiàn)了重復(fù)項,忽略此項即可。
function unique(arr) { const obj = {}; // 這里可以換成Map const newArr = []; for (let i = 0; i < arr.length; i++) { const item = arr[i]; if (!obj[item]) { obj[item] = 1; newArr.push(item); } } return newArr; }
這也是典型的空間換時間大法,可以讓時間復(fù)雜度從O(n²)降為O(n),利用對象存儲,達到空間換時間的效果,節(jié)約執(zhí)行時間。
三、最好理解的去重:indexOf + lastIndexOf
JavaScript
中提供了indexOf
和lastIndexOf
兩個方法,分別拿目標(biāo)項從數(shù)組的第一項和最后一項開始查找,查到了會返回對應(yīng)的索引值,如果某一項用indexOf
和lastIndexOf
找到的索引相同,則證明該項不存在重復(fù)項,反之就存在重復(fù)項。
這種去重方式應(yīng)該是最好理解的。不過要注意,這里也使用了splice
,需要注意處理防止數(shù)組塌陷的問題。
function unique(arr) { for (let i = 0; i < arr.length; i++) { if (arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])) { arr.splice(i, 1); i--; // 注意:由于刪除了元素,需要將 i 減一,以避免漏掉第i項的檢查 } } return arr; }
四、最簡單的去重:展開運算符 + Set
利用ES6
的新特性,也就是展開運算符 + set應(yīng)該是最簡單的去重方式,寫的字符數(shù)也是最少的。
function unique(arr) { return [...new Set(arr)]; }
五、最有趣的去重:filter + indexOf去重
利用filter
+ indeOf
其實也可以實現(xiàn)去重,而且是一行代碼搞定,非常有趣。
核心的思路就是,在用filter
遍歷時,用indexOf
去查找當(dāng)前遍歷項的索引,如果查找到的索引與此時filter
遍歷的index
一樣,那么說明在當(dāng)前項之前是沒出現(xiàn)與當(dāng)前項相同的重復(fù)項的,所以該項需要保留
,反之則需要剔除
,而正好filter
自帶過濾功能,返回true
保留該項,返回false
剔除該項。
function unique(arr) { return arr.filter((item, index) => arr.indexOf(item) === index); } const arr = [1,1,2,2,3,4,4,5,5,6]; console.log(unique(arr)); // 輸出:[ 1, 2, 3, 4, 5, 6 ]
六、最騷的去重:JSON.stringify + Set + JSON.parse
想不到吧,利用JSON.stringify
+ Set
+ JSON.parse
居然也可以實現(xiàn)去重,這應(yīng)該是最騷的去重方式了,而且天然就支持對存放數(shù)組的對象進行去重。
去重的核心思路如下:
- 利用
JSON.stringify
可以將數(shù)組每一項存儲的對象或者普通值都進行序列化,將原數(shù)組轉(zhuǎn)為一個字符串?dāng)?shù)組; - 利用
Set
對字符串?dāng)?shù)組進行去重; - 利用
JSON.parse
對數(shù)組每一項進行反序列化。
這里注意,如果兩個對象存的key和value都相同,則他們序列化的結(jié)果也相同,所以說這種方式是天然支持對對象進行去重的。
function unique(arr) { return [...new Set(arr.map(t => JSON.stringify(t)))].map(s => JSON.parse(s)); } const arr = [1,1,2,2,3,4,4,5,5,6]; const arr1 = [{ a:1 }, { a:1 }, { a:2 }, { a:2 }, { a:3 }, { a:3 }, { a:4 }, { a:4 }, { a:5 }, { a:5 } ] console.log(unique(arr)); console.log(unique(arr1)); /** * 打印結(jié)果: * [ 1, 2, 3, 4, 5, 6 ] * [ { a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }, { a: 5 } ] */
以上介紹了6種JavaScript
去重方式,我平常最常用的就是第四種,也就是展開運算符 + Set去重,不知道大家在平時實際開發(fā)中更喜歡哪一種去重方式呢,或者還有沒有其它的更好去重方式呢?
到此這篇關(guān)于JavaScript數(shù)組去重的六種方式的文章就介紹到這了,更多相關(guān)JavaScript數(shù)組去重內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實現(xiàn)兼容IE6的收起折疊與展開效果實例
這篇文章主要介紹了JavaScript實現(xiàn)兼容IE6的收起折疊與展開效果,結(jié)合具體實例形式分析了javascript事件響應(yīng)及針對頁面元素屬性的動態(tài)操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2017-09-09Echats圖表大屏自適應(yīng)的實現(xiàn)方法
很多時候我們需要用圖表來制作我們統(tǒng)計的數(shù)據(jù)直觀的分析,所以我們可以用Echarts來制作圖表,這篇文章主要給大家介紹了關(guān)于Echats圖表大屏自適應(yīng)的實現(xiàn)方法,需要的朋友可以參考下2021-10-10JavaScript對JSON數(shù)據(jù)進行排序和搜索
今天教給大家如何使用數(shù)組的方法來實現(xiàn)JSON數(shù)據(jù)進行排序和搜索功能,具體實例代碼大家參考下本文吧2017-07-07ES6?關(guān)鍵字?let?和?ES5?及關(guān)鍵字?var?的區(qū)別解析
var可以穿透控制語句、條件語句這樣的作用域,導(dǎo)致變量沖突經(jīng)常發(fā)生,這篇文章主要介紹了ES6?關(guān)鍵字?let?和?ES5?及關(guān)鍵字?var?的區(qū)別,需要的朋友可以參考下2022-09-09layui實現(xiàn)鼠標(biāo)移動到單元格上顯示數(shù)據(jù)的方法
今天小編就為大家分享一篇layui實現(xiàn)鼠標(biāo)移動到單元格上顯示數(shù)據(jù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09微信小程序scroll-view組件實現(xiàn)滾動動畫
這篇文章主要為大家詳細介紹了微信小程序scroll-view組件實現(xiàn)滾動動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01three.js中正交與透視投影相機的實戰(zhàn)應(yīng)用指南
在three.js中攝像機的作用就是不斷的拍攝我們創(chuàng)建好的場景,然后通過渲染器渲染到屏幕中,下面這篇文章主要給大家介紹了關(guān)于three.js中正交與透視投影相機應(yīng)用的相關(guān)資料,需要的朋友可以參考下2022-08-08關(guān)于onScroll事件在IE6下每次滾動觸發(fā)三次bug說明
今天測試發(fā)現(xiàn)IE6下用window.onscroll,每次滾動時會觸發(fā)3次,而火狐、IE7沒此問題,應(yīng)該是IE6的一個BUG2011-09-09