摘要:總結,其實數組去重無非就是判斷一個元素在數組中是否有重復的值。參考自從數組去重談性能優化也談數組去重數組去重謝謝飛的更高指出的問題同步于個人博客
javascript 數組 array 去重 distinct unique
剛好前天面試的時候面試官問到了數組去重的問題,當時有點語塞只想到用了兩個循環檢測(其實模模糊糊想到了hash的方法做但是由于記得不清不敢說= =?。?,思路是檢測是否有元素重復,然后將只出現一次的元素推入到新數組中,然后返回新數組。然后面試官又問這種方法的時間效率,于是黑線了。so這兩天看了一下相關的文章,在這里也總結一下javascript數組去重的方法。
兩層循環檢測重復元素法首先,介紹一下大家都會想到的兩層循環的demo,如下例:
function distinct(arr) { var ret = [], length = arr.length; for(var i = 0;i < length; i++){ for(j = i+1; j
如上的代碼實現是輕松易得的,思路如下:首先外層循環比遍歷整個數組
內層循環匹配是否有值重復
a.如判斷有相同元素則自增i變量,跳出i的循環 b.如判斷無時則將無相等值的元素推入到ret數組中3.返回ret。
優點:便捷易懂,大多數程序員能想到。
缺點:很明顯時間消耗太高,兩層循環時間消耗太多,時間的消耗為O(n^2^),在進行大量數據處理時會消耗大量資源。而且該方法無法處理字符和數組,如下例:var arr = [1,23,4,5,6,7,"1",22,3,1,2]; distinct(arr); //返回[23, 4, 5, 6, 7, "1", 22, 3, 1, 2]所以我們可以開始考慮一些別的方法優化數組去重:
sort重排數組去除重復元素索引法(!每一個瀏覽器中的sort函數的排序方法并不一樣,所以實現結果可能會有差異,經測試在chrome下測試別的數組實現會出現問題)這種方法就是先講原數組使用sort方法將數組重排,以得到將相同元素為相鄰位的一個新數組。該方法如下:
function distinct(arr){ var self = arr; list = self.concat().sort(); list.sort(function(a, b){ if(a === b){ var ind = self.indexOf(a); self.splice(ind, 1); } }); return self; } var arra = [1,2,3,3,1,1,1,"1"]; var arr = distinct(arra); //返回的數組為[2,3,1,"1"]同樣的,在使用這種方法的重排的時候,仍然會有一定的資源消耗,在sort()函數中回調函數是使用的冒泡排序,而冒泡排序的效率并不高。但是使用這種方法的效率仍然比上一種方法的效率高,因為在此例中只出現了一次循環遍歷。
優點:程序簡潔,效率較高。
缺點:1.仍然無法解決數字1和字符"1"的去除。2.依賴indexOf方法,我們知道在IE6~8中并未支持indexOf()方法。
所以我們還要做一些兼容性的處理。如下:var indexOf = [].indexOf ? function indexOf(arr, item){ return arr.indexOf(item); }: function indexOf(arr, item){ for(var i = 0; i < arr.length; i++){ if(arr[i] === item){ retrun i; } } return -1; } function distinct(arr){ var self = arr; list = self.concat().sort(); list.sort(function(a, b){ if(a === b){ var ind = self.indexOf(arr, a); self.splice(ind, 1); } }); return self; }將數組元素值存為對象的屬性function distinct(arr) { var ret = [], json = {}, length = arr.length; for(var i = 0; i < length; i++){ var val = arr[i]; if(!json[val]){ json[val] = 1; ret.push(val); } } return ret; } var arra = [1,2,3,5,7,1,2,"1"];以上方法更加的簡潔,而且也能在原來的基礎上區分字符‘1’和數字1的區別。
在此例中思路如下:
1.循環遍歷每一個元素
2.檢測在json對象中是否含遍歷到的元素的值a: 如果是則跳過 b: 如果否存入json對象中該屬性名的值設為13.將存入對象了元素的值推入到新數組中,返回新數組。
總結,其實數組去重無非就是判斷一個元素在數組中是否有重復的值。優化也是一直改變判定元素是否重復的一些技巧,如例1中是遍歷數組,例2是重排數組獲得索引,例3則別出心裁將元素的值作為對象的屬性。
參考自:
從 JavaScript 數組去重談性能優化
也談javascript數組去重
js數組去重
謝謝@飛的更高 指出的問題同步于個人博客:http://penouc.com
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78122.html
摘要:一語法其中,表示將要原數組表示上一次調用回調時的返回值,或者初始值表示當前正在處理的數組元素表示當前正在處理的數組元素的索引,若提供值,則索引為,否則索引為表示初始值。 一、語法 arr.reduce(function(prev,cur,index,arr){...}, init); 其中,arr 表示將要原數組;prev 表示上一次調用回調時的返回值,或者初始值 init;cur 表...
摘要:前言昨天跟在前端好友聊天時,她提到了一個問題數組去重你會怎么寫。利用將結構轉換成數組拓展運算符內部使用循環參考淺談數組去重數組去重小結標準入門第版 前言 昨天跟在前端好友聊天時,她提到了一個問題:數組去重你會怎么寫?。想了想,其實有好幾種方法,決定在這篇筆記中做一些記錄。 思路一: 雙層循環,外層循環元素,內層循環時比較值 如果有相同的值則跳過,不相同則push進數組 Array....
摘要:設計模式是以面向對象編程為基礎的,的面向對象編程和傳統的的面向對象編程有些差別,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續了解設計模式必須要先搞懂面向對象編程,否則只會讓你自己更痛苦。 JavaScript 中的構造函數 學習總結。知識只有分享才有存在的意義。 是時候替換你的 for 循環大法了~ 《小分享》JavaScript中數組的那些迭代方法~ ...
摘要:忍者級別的函數操作對于什么是匿名函數,這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數是一個很重要且具有邏輯性的特性。通常,匿名函數的使用情況是創建一個供以后使用的函數。 JS 中的遞歸 遞歸, 遞歸基礎, 斐波那契數列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果...
摘要:是解釋性語言因服務端的應用,而貫通了前后臺。關于和聲明的變量和聲明的變量整體,會被提升到當前作用域的頂部。做后臺服務端,處理請求的代碼,得自己實現了。為提高下載速度,可通過來切換鏡像源。 JS是解釋性語言,因node服務端的應用,而貫通了前后臺。 【ES6】 關于var和let var: 1.var聲明的變量和function聲明的變量整體,會被提升到當前作用域的頂部。 2...
閱讀 1443·2021-11-22 13:54
閱讀 4327·2021-09-22 15:56
閱讀 1815·2021-09-03 10:30
閱讀 1318·2021-09-03 10:30
閱讀 2086·2019-08-30 15:55
閱讀 1851·2019-08-30 14:13
閱讀 2059·2019-08-29 15:19
閱讀 2341·2019-08-28 18:13