Javascript中數(shù)組去重與拍平的方法示例
數(shù)組的判斷
在說(shuō)如何進(jìn)行數(shù)組的去重和拍平之前,先說(shuō)一下怎么判斷數(shù)組,因?yàn)橐M(jìn)行數(shù)組的處理當(dāng)然要先判斷下傳過(guò)來(lái)的數(shù)據(jù)是不是數(shù)組。
首先我們都知道js的數(shù)據(jù)類(lèi)型只有5種,分別是Undefined、Null、Boolean、Number和String,數(shù)組只是一個(gè)對(duì)象,用typeof([])返回的結(jié)果知識(shí)一個(gè)Object的字符串,因此我們需要通過(guò)其他手段來(lái)判斷它,這里就說(shuō)兩種方法。
第一種用instenceof方法
instanceof是ES5提供的一個(gè)方法,它可以用來(lái)判斷實(shí)例是否是某個(gè)類(lèi)的實(shí)例,例如:
[] instenceof Array //返回結(jié)果是true
這種方法的不好之處就是兼容性不好,對(duì)于一些低版本瀏覽器不支持ES5的就要懵逼了。
第二種方法是通過(guò)原型鏈的方式來(lái)判斷
了解js的話都應(yīng)該懂得js這個(gè)語(yǔ)言的特點(diǎn)就是原型鏈?zhǔn)降模械膶?duì)象都繼承自Object.prototype,而prototype上又有toString()方法,這個(gè)toString()方法是干什么用的呢?就是以字符串的形式返回當(dāng)前對(duì)象的值。第一次看可能這句話可能不大明白,舉個(gè)例吧:
var num = 123; num.toString(); //返回結(jié)果為"123"
有沒(méi)有看明白一點(diǎn)?就是返回num這個(gè)對(duì)象值的字符串形式,也就是”123”。好了,這跟判斷數(shù)組有什么關(guān)系?想一下所有的對(duì)象都繼承自Object.prototype,數(shù)組也是啊,如果把一個(gè)數(shù)組送到Object.prototype里作為一個(gè)“值”,在調(diào)用toString()方法,那它應(yīng)該顯示出這個(gè)對(duì)象的名字才對(duì)啊,這就是判斷的原理,代碼如下:
Object.prototype.toString.call([]); //結(jié)果是"[object Array]"
像jQuery這樣的腳本庫(kù)的isArray()用的就是這個(gè)方法。
數(shù)組拍平
說(shuō)完判直奔主題,先是數(shù)組拍平,什么是數(shù)組拍平呢?就是把[1,[2,[3,4],5]]鋪成[1,2,3,4,5]。關(guān)于數(shù)組拍平我有兩種思路,第二種比較奇葩,留點(diǎn)懸念吧哈哈。
第一種是常規(guī)思路
對(duì)數(shù)組進(jìn)行遍歷,如果數(shù)組里面套著數(shù)組就繼續(xù)遍歷里面的,直到把每個(gè)元素都遍歷完,然后一邊遍歷一邊塞入新的數(shù)組變量里,這樣就完成拍平了,具體代碼如下:
panelArr = function(arr){
var newArr = [];
var isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
var dealArr = function(arr){
for (var i = 0;i<arr.length;i++){
isArray(arr[i]) ? dealArr(arr[i]) : newArr.push(arr[i]);
}
};
dealArr(arr);
return newArr;
};
console.log(panelArr([1,[2,3]])); //[1,2,3]
當(dāng)然這個(gè)方法也可以寫(xiě)在Array.prototype里,使用起來(lái)更方便。這個(gè)方法有個(gè)問(wèn)題就是內(nèi)存占用上,因?yàn)椴捎眠f歸如果數(shù)據(jù)量大了會(huì)占用大量大量?jī)?nèi)存。
第二種奇葩思路
第二種思路就是不把數(shù)組來(lái)看,也不遍歷了直接拍平。聽(tīng)起來(lái)略奇怪,怎么能不遍歷就拍平?就是使用join()方法,將數(shù)組轉(zhuǎn)換成字符串,然后正則去掉符號(hào)最后合并,這個(gè)方法在使用注意不能join("") ,因?yàn)槿绻@樣分割的話,13是1和3還是13?不好區(qū)分,代碼如下:
var arr = [1,2,[33,43],20,19];
arr.join(".").replace(/,/g,".").split("."); //["1", "2", "33", "43", "20", "19"]
注意:這個(gè)方法會(huì)轉(zhuǎn)換數(shù)據(jù)類(lèi)型成字符串。
數(shù)組去重
下面是數(shù)組去重,舉例來(lái)說(shuō)就是[1,2,3,3,4,5,5,5,6]變成[1,2,3,4,5,6]。這個(gè)實(shí)現(xiàn)的核心就是去重這里,如果能夠快速判斷元素是否重復(fù)就是關(guān)鍵。
還是兩種思路
第一種遍歷的思路
就是準(zhǔn)備一個(gè)新的數(shù)組變量,塞入前每次對(duì)這個(gè)變量進(jìn)行遍歷看看是否有重復(fù)的,如果沒(méi)有就塞入,最后生成的新數(shù)組就是去重后的數(shù)組了。示例代碼如下:
function uniqueArr(arr){
var newArr = [];
newArr.push(arr[0]);
for(var i = 1; i<arr.length;i++){
var repeat = false;
for(var j = 0;j<newArr.length;j++){
if(arr[i] == newArr[j]){
repeat = true;
}
}
if(!repeat){
newArr.push(arr[i]);
}
}
return newArr;
}
第二種使用哈希判斷
上面那個(gè)時(shí)間復(fù)雜度為O(n^2)的方法并不是什么好方法,它的瓶頸就是判斷是否重復(fù)這里,所以我們換成一個(gè)更高效的檢索是否重復(fù)的方法,這個(gè)方法就是哈希,為什么哈希檢索最快?翻翻數(shù)據(jù)結(jié)構(gòu)吧,這里就不在贅述了。
這個(gè)方法的思路就是在原始數(shù)組和去重?cái)?shù)組之間加入一個(gè)哈希過(guò)濾,總的來(lái)看就是原數(shù)組數(shù)據(jù)交給哈希,看是否有重復(fù),若是沒(méi)有則添加進(jìn)去。具體代碼如下:
function uniqueArr(arr){
var newArr = [],
hashFilter = {};
for(var i = 0;i<arr.length;i++){
if(!hashFilter[arr[i]]){
//若不存在將此屬性對(duì)應(yīng)的值改為true,并塞入去重?cái)?shù)組中
hashFilter[arr[i]] = true;
newArr.push(arr[i]);
}
}
return newArr;
}
我青睞第二種,因?yàn)樵谂袛嗍欠裰貜?fù)這里真的很快,可以說(shuō)是秒出。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
相關(guān)文章
原生javaScript做得動(dòng)態(tài)表格(注釋寫(xiě)的很清楚)
因?yàn)榭垂竞枚嘤脛?dòng)態(tài)表格的,所以,我就試著用js做了動(dòng)態(tài)表格,下面有個(gè)不錯(cuò)的示例,感興趣的朋友可以參考下2013-12-12
基于微信小程序?qū)崿F(xiàn)人臉數(shù)量檢測(cè)的開(kāi)發(fā)步驟
最近項(xiàng)目需求是統(tǒng)計(jì)當(dāng)前攝像頭中的人臉個(gè)數(shù),所以下面這篇文章主要給大家介紹了關(guān)于基于微信小程序?qū)崿F(xiàn)人臉數(shù)量檢測(cè)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12
網(wǎng)絡(luò)圖片延遲加載實(shí)現(xiàn)代碼 超越j(luò)query控件
原理是分段加載圖片,主要用于大型網(wǎng)站節(jié)省帶寬,可是他們提供的東西壓縮混淆看不清,還有的要基于什么雅虎的什么庫(kù),總之是很麻煩的,JQ的控件倒是夠清晰了,只是還是沒(méi)有達(dá)到節(jié)省網(wǎng)絡(luò)帶寬的效果2010-03-03
javascript強(qiáng)制點(diǎn)擊廣告的方法
這篇文章主要介紹了javascript強(qiáng)制點(diǎn)擊廣告的方法,可用于下載站或文檔顯示站,實(shí)現(xiàn)點(diǎn)擊后才能出現(xiàn)相應(yīng)顯示的功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-02-02
Chrome不支持showModalDialog模態(tài)對(duì)話框和無(wú)法返回returnValue問(wèn)題的解決方法
上個(gè)禮拜修改測(cè)試一個(gè)后臺(tái)管理項(xiàng)目,在測(cè)試與各個(gè)瀏覽器兼容性的時(shí)候,發(fā)現(xiàn)在chrome瀏覽器下showModalDialog方法顯示的并不是模態(tài)對(duì)話框,就像新打開(kāi)一個(gè)頁(yè)面一樣,父窗口仍然可以隨意獲取焦點(diǎn),并可以打開(kāi)多個(gè)窗體,而且返回值returnValue也無(wú)法返回,一直是undefined2016-10-10
兩款JS腳本判斷手機(jī)瀏覽器類(lèi)型跳轉(zhuǎn)WAP手機(jī)網(wǎng)站
本文通過(guò)兩款js腳本判斷手機(jī)瀏覽器類(lèi)型跳轉(zhuǎn)到wap手機(jī)網(wǎng)站,感興趣的小伙伴快來(lái)學(xué)習(xí)吧2015-10-10
Bootstrap modal使用及點(diǎn)擊外部不消失的解決方法
這篇文章主要為大家詳細(xì)介紹了Bootstrap modal使用及點(diǎn)擊外部不消失的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12

