JavaScript數(shù)組去重的幾種方法
前言
有時(shí)候我們做項(xiàng)目的時(shí)候往往會(huì)需要把數(shù)組里面一些重復(fù)的項(xiàng)去掉,但是原生JS有排序,有篩選等等,但是就是沒有數(shù)組去重怎么辦呢?
這能怎么辦,自己手動(dòng)實(shí)現(xiàn)嘛。
數(shù)組不像對(duì)象和hash有唯一的標(biāo)志特征(key)。所以,數(shù)組去重的核心就是【1】數(shù)組內(nèi)元素互相比較,然后放入新的數(shù)組中?!?】參照對(duì)象構(gòu)建一個(gè)唯一的特征標(biāo)志,然后放入新數(shù)組中。以下就是依照這種思路產(chǎn)生的方法?!?】數(shù)組中含對(duì)象的去重方式我采用使用JSON.stringify()
將對(duì)象轉(zhuǎn)換成JSON字符串進(jìn)行比較的方式。
1.最基礎(chǔ)的去重:雙重遍歷
雙重遍歷的核心就是依據(jù)【1】,通過拿出一個(gè)元素和剩下的元素依次比較,如果全部不相等則證明此元素為唯一。
let a=[{a:1},{b:2},{c:3},{a:1},{d:2}] let c=[1,2,3,4,5,6,1,2,3] function unique(arr){ let b=[] for(let i=0;i<arr.length;i++){ let unexit=true for(let j=i+1;j<arr.length;j++){ if(JSON.stringify(arr[i])===JSON.stringify(arr[j])){ unexit=false break } else{ unexit=true } } if(unexit){ b.push(arr[i]) } } return b }
關(guān)于數(shù)組中存在對(duì)象,是采用JSON.stringify()
轉(zhuǎn)換成JSON字符串進(jìn)行的比較,后續(xù)不再敘述。雙重遍歷的缺點(diǎn)是復(fù)雜度太高。
上面的代碼去重得到的結(jié)果的順序會(huì)改變,所以如果想要順序按照原有順序,數(shù)組在進(jìn)行去重時(shí)建議重新申明一個(gè)新的數(shù)組(var new=old.reverse()
)得到一個(gè)新的相反的數(shù)組,最后再使用reverse()。之所以新建數(shù)組而不是直接取反是因?yàn)椋?code>reverse()會(huì)修改原數(shù)組。
2.Array.prototype.sort():相鄰元素去重
相鄰元素去重的核心在于Array.sort()
能夠?qū)?shù)組進(jìn)行排序。這樣相等的數(shù)組就會(huì)在相鄰的位置,通過比較相鄰的元素就可以起到去重的作用【1】。
let c=[1,2,3,4,5,6,1,2,3] function unique(arr){ let Arr=arr.sort() let b=[] for(let i=0;i<Arr.length;i++){ if(Arr[i]!==Arr[i+1]){ b.push(Arr[i]) } } return b }
Array.prototype.sort()
方法可以使用array.sort((a,b)=>{a.key-b.ky})
進(jìn)行對(duì)象的排序,前提是數(shù)組中的對(duì)象存在相同的key值。
3.Object.keys():存在唯一性
在一個(gè)對(duì)象里面key值是唯一的,所以通過遍歷數(shù)組給每個(gè)數(shù)組一個(gè)標(biāo)志,通過標(biāo)志去重【2】
let a=[{a:1},{b:2},{c:3},{a:1},{d:2}] let c=[1,2,3,4,5,6,1,2,3] function unique(arr){ let b=[] let hash={} for(let i=0;i<arr.length;i++){ if(!hash[JSON.stringify(arr[i])]){ hash[JSON.stringify(arr[i])]=true b.push(arr[i]) } } return b }
4.雙重遍歷去重改良之:indexOf
雙重遍歷的思路我們都知道,先拿出一個(gè)元素,然后使用循環(huán)再次遍歷數(shù)組去一一比較。如果有一個(gè)方式能夠讓我們不再遍歷一遍數(shù)組,那么復(fù)雜度相對(duì)而言會(huì)減少一點(diǎn)。
indexOf 方法返回給定元素在數(shù)組中第一次出現(xiàn)的位置,如果沒有出現(xiàn)則返回-1。首先我們新建一個(gè)空數(shù)組(arry),如果:arry.indexOf
(數(shù)組元素)===-1,那么我們就可以知道arry中不存在元素。
let c=[1,2,3,4,5,6,1,2,3] function unique(arr){ let b=[] for(let i=0;i<arr.length;i++){ if(b.indexOf(arr[i])==-1){ b.push(arr[i]) } } return b }
indexOf 方法可返回某個(gè)指定的字符串值在字符串中首次出現(xiàn)的位置。所以對(duì)象不適用,因?yàn)閷?duì)象轉(zhuǎn)為字符串就都會(huì)變成{object,object}
,無法比較。
5.循環(huán)遍歷之:map()/forEach()
map()和forEach()都可以實(shí)現(xiàn)遍歷數(shù)組。所以以上的方法都可以用map()、forEach()改寫。下面我只簡單的改寫一個(gè),其他的改寫方式參照即可。
let c=[1,2,3,4,5,6,1,2,3] function unique(arr){ let b=[] arr.forEach(res=>{ if(b.indexOf(res)==-1){ b.push(res) } }) return b }
6.ES6:Set數(shù)據(jù)結(jié)構(gòu)
Set數(shù)據(jù)類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值。它可以接收一個(gè)數(shù)組,類于:let a=[1,2,3,1,2] Set(a)=>1,2,3
所以可以使用Set()實(shí)現(xiàn)去重。
let c=[1,2,3,4,5,6,1,2,3] function unique(arr){ let b=new Set(arr) let c=Array.from(b) return c }
Set去重不適用于含對(duì)象的數(shù)組,因?yàn)镾et的去重參照的是(===),數(shù)組中的元素對(duì)象,雖然可能數(shù)值相等,但是地址不相等。所以Set無法實(shí)現(xiàn)去重。
7.總結(jié)
實(shí)現(xiàn)數(shù)組的去重,要么通過元素對(duì)比,要么設(shè)置特殊標(biāo)志識(shí)別。元素對(duì)比的思路有2種:一種是和原數(shù)組一一對(duì)比;另一種和新的數(shù)組對(duì)比。
如果要實(shí)現(xiàn)含對(duì)象的數(shù)組去重,一般使用遍歷的方式,包括使用遍歷類的方法(map、forEach、reduce等)。像Set、sort等通過改變數(shù)組的方式一般是不可行的。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
基于JavaScript實(shí)現(xiàn)手機(jī)短信按鈕倒計(jì)時(shí)(超簡單)
在淘寶等購物網(wǎng)站,我們都會(huì)看到一個(gè)發(fā)送短信倒計(jì)時(shí)的按鈕,究竟是如何實(shí)現(xiàn)的呢?下面小編通過本篇文章給大家分享一段代碼關(guān)于js實(shí)現(xiàn)手機(jī)短信按鈕倒計(jì)時(shí),需要的朋友參考下2015-12-12一些常用的JavaScript函數(shù)(json)附詳細(xì)說明
一些常用的JavaScript函數(shù)(json)附詳細(xì)說明,學(xué)習(xí)js的朋友可以參考下。2011-05-05JS實(shí)現(xiàn)對(duì)JSON數(shù)據(jù)進(jìn)行冒泡排序
JavaScript 是一種廣泛使用的腳本語言,JSON是一種常見的數(shù)據(jù)格式,這篇文章主要來探討一下如何使用 JavaScript 對(duì) JSON 數(shù)據(jù)進(jìn)行冒泡排序,感興趣的可以了解一下2023-06-06javascript實(shí)現(xiàn)2016新年版日歷
這篇文章主要為大家介紹了javascript實(shí)現(xiàn)2016新年版日歷的詳細(xì)代碼,感興趣的小伙伴們可以參考一下2016-01-01原生JavaScript實(shí)現(xiàn)滾動(dòng)條效果
這篇文章主要介紹了原生JavaScript實(shí)現(xiàn)滾動(dòng)條效果的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01KnockoutJS 3.X API 第四章之表單value綁定
Knockout是一個(gè)以數(shù)據(jù)模型(data model)為基礎(chǔ)的能夠幫助你創(chuàng)建富文本,響應(yīng)顯示和編輯用戶界面的JavaScript類庫。這篇文章主要介紹了KnockoutJS 3.X API 第四章之表單value綁定的相關(guān)資料,需要的朋友可以參考下2016-10-10

JS實(shí)現(xiàn)把一個(gè)頁面層數(shù)據(jù)傳遞到另一個(gè)頁面的兩種方式