javascript 陣列去重的6種思路

2021-09-14 01:30:39 字數 2808 閱讀 3015

前端在日常開發中或多或少都會碰到有對資料去重的需求,實際上,像是lodash這些工具庫已經有成熟完備的實現,並且可以成熟地運用於生產環境。但是這並不妨礙我們從思維拓展的角度出發,看看去重可以用幾種思路去實現。
首先是常規的雙層迴圈比對的思路實現

function doubleloopuniq(arr) 

}// 最後判斷如果不存在,則將此元素插入result

!i***ist && result.push(arr[i]);

} return result;

}

借助 js內建的indexof 進行去重

function indexofuniq(arr) 

return result;

}

排序後前後比對去重

function sortuniq(arr) 

});return result;

}

通過hashtable去重

function hashuniq(arr) , {})

return object.keys(hashtable).map(item => parseint(item, 10));

}

es6 set一行**實現去重

function tosetuniq(arr)
splice 去重(直接運算元組本身,帶***)

function inplaceuniq(arr) 

++compare

}++idx;

} return arr;

}

最後在nodejs下面簡單跑個測試,看看哪個效率高~

let data = ;

for (var i = 0; i < 100000; i++)

// 實現乙個效能測試的裝飾器

function performancetest(fn, descript)

}performancetest(hashuniq, "hashtable")(data)

performancetest(sortuniq, "sortuniq")(data)

performancetest(tosetuniq, "tosetuniq")(data)

performancetest(indexofuniq, "indexofuniq")(data)

performancetest(doubleloopuniq, "doubleloopuniq")(data)

performancetest(inplaceuniq, "inplaceuniq")(data)

結果如下

hashtable 168ms

sortuniq 332ms

tosetuniq 80ms

indexofuniq 4280ms

doubleloopuniq 13303ms

inplaceuniq 9977ms

延伸思考: 如果陣列內的元素是物件該怎麼去重呢?

既然是引用型別,那麼不免會使用到deepequal,固然這種思路可以解答這道問題,但難免不夠高效。

從上面的測試中也可見通過new set 和 hashtable 去重是最高效的。

所以毫無疑問,我們要基於這兩種方式去改造,我想用的是hashtable,

另一方面,為了降低深度比較帶來的耗時,我嘗試用json.stringify 將引用型別轉化為基本型別。

function collectionuniq(collection) ;

collection.foreach(item => )

return object.keys(hashtable).map(item => json.parse(item))

}

那麼問題來了,我們都知道物件的屬性是無序的,假如資料是這種情況,那就gg了。

let collection = [ ,  ]
有一種tohash的思路,在對這個陣列進行一次基本的去重之後,為了保證準確,

先遍歷json 字串 =>

通過 charcodeat()拿到每個字串 的 unicode 編碼 =>

相加得到乙個總數,最後再兩兩進行比較,數值相等的就是重複的,這樣就達到去重的效果了。

function tohash(obj) ':

power /= 2

break

case ' ':

case '\n':

case '\r':

case '\t':

break

default:

res += string[i].charcodeat(0) * power

}} return res

}

這只是乙個實現基本的思路,有很大的改進空間,為了減少hash碰撞的可能,可以對一些特殊字元進行權重的增減。

重點是保證碰撞的機率小到比中大獎還小就可以了。

2018.2.8

上面是乙個比較清奇的思路,常規的做法,實際上還是應該從優化深度比較的效率入手。

看到乙個很好的實現思路,是乙個優先判錯的思路,通過預設各種前置條件來避免高代價的迴圈,這種思路儘管在資料量小的時候因為前置判斷可能有一些微乎其微的效能損耗,但是資料量越大,優勢就越明顯了。感興趣的可以了解下。

JavaScript 陣列去重

陣列去重,一般都是在面試的時候才會碰到,一般是要求手寫陣列去重方法的 如果是被提問到,陣列去重的方法有哪些?你能答出其中的10種,面試官很有可能對你刮目相看。在真實的專案中碰到的陣列去重,一般都是後台去處理,很少讓前端處理陣列去重。雖然日常專案用到的概率比較低,但還是需要了解一下,以防面試的時候可能...

Javascript陣列去重

set是es2015引入的資料型別,意為集合 其不允許重複元素出現的特性,對於nan undefined null都適用 set是es2015引入的資料型別,意為集合 其不允許重複元素出現的特性,對於nan undefined null都適用 function unique arr var arr ...

JavaScript陣列去重

例1定義乙個簡單的一維陣列 let myarr 0 1,3 2,4 3,3 4,5 6,1 7,8 方法一 使用es6的set let myarr 0 1,3 2,4 3,3 4,5 6,1 7,8 let result newset myarr sort a,b console.log resul...