国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

javascript 數(shù)組去重的6種思路

AlphaWallet / 2281人閱讀

摘要:但是這并不妨礙我們從思維拓展的角度出發(fā),看看去重可以用幾種思路去實(shí)現(xiàn)。首先是常規(guī)的雙層循環(huán)比對(duì)的思路實(shí)現(xiàn)定義一個(gè)變量表示當(dāng)前元素在中是否存在。依次對(duì)中的元素和原數(shù)組元素進(jìn)行比對(duì)。重點(diǎn)是保證碰撞的幾率小到比中大獎(jiǎng)還小就可以了。

</>復(fù)制代碼

  1. 前端在日常開發(fā)中或多或少都會(huì)碰到有對(duì)數(shù)據(jù)去重的需求,實(shí)際上,像是lodash這些工具庫已經(jīng)有成熟完備的實(shí)現(xiàn),并且可以成熟地運(yùn)用于生產(chǎn)環(huán)境。但是這并不妨礙我們從思維拓展的角度出發(fā),看看去重可以用幾種思路去實(shí)現(xiàn)。

首先是常規(guī)的雙層循環(huán)比對(duì)的思路實(shí)現(xiàn)

</>復(fù)制代碼

  1. function doubleLoopUniq(arr) {
  2. let result = [];
  3. for (let i = 0, len = arr.length, isExist; i < len; i++) {
  4. // 定義一個(gè)變量表示當(dāng)前元素在 result 中是否存在。
  5. isExist = false;
  6. for (let j = 0, rLen = result.length; j < rLen; j++) {
  7. if (result[j] === arr[i]) {
  8. // 依次對(duì)result 中的元素 和 原數(shù)組元素進(jìn)行比對(duì)。
  9. isExist = true;
  10. break;
  11. }
  12. }
  13. // 最后判斷如果不存在,則將此元素插入result
  14. !isExist && result.push(arr[i]);
  15. }
  16. return result;
  17. }

借助 js內(nèi)置的indexOf 進(jìn)行去重

</>復(fù)制代碼

  1. function indexOfUniq(arr) {
  2. let result = [];
  3. for (let i = 0, len = arr.length; i < len; i++) {
  4. // 用indexOf 簡化了二層循環(huán)的流程
  5. if (result.indexOf(arr[i]) === -1) result.push(arr[i]);
  6. }
  7. return result;
  8. }

排序后前后比對(duì)去重

</>復(fù)制代碼

  1. function sortUniq(arr) {
  2. let result = [], last;
  3. // 這里解構(gòu)是為了不對(duì)原數(shù)組產(chǎn)生副作用
  4. [ ...arr ].sort().forEach(item => {
  5. if (item != last) {
  6. result.push(item);
  7. last = item;
  8. }
  9. });
  10. return result;
  11. }

通過hashTable去重

</>復(fù)制代碼

  1. function hashUniq(arr) {
  2. let hashTable = arr.reduce((result, curr, index, array) => {
  3. result[curr] = true;
  4. return result;
  5. }, {})
  6. return Object.keys(hashTable).map(item => parseInt(item, 10));
  7. }

ES6 SET一行代碼實(shí)現(xiàn)去重

</>復(fù)制代碼

  1. function toSetUniq(arr) {
  2. return Array.from(new Set(arr));
  3. }

splice 去重(直接操作數(shù)組本身,帶副作用)

</>復(fù)制代碼

  1. function inPlaceUniq(arr) {
  2. let idx = 0;
  3. while (idx < arr.length) {
  4. let compare = idx + 1;
  5. while (compare < arr.length) {
  6. if (arr[idx] == arr[compare]) {
  7. arr.splice(compare, 1);
  8. continue;
  9. }
  10. ++compare
  11. }
  12. ++idx;
  13. }
  14. return arr;
  15. }

最后在nodejs下面簡單跑個(gè)測試,看看哪個(gè)效率高~

</>復(fù)制代碼

  1. let data = [];
  2. for (var i = 0; i < 100000; i++) {
  3. data.push(Math.random())
  4. }
  5. // 實(shí)現(xiàn)一個(gè)性能測試的裝飾器
  6. function performanceTest(fn, descript) {
  7. var a = new Date().getTime();
  8. return function () {
  9. fn.apply(this, [].slice.call(arguments, 0));
  10. console.log(descript, new Date().getTime() - a)
  11. }
  12. }
  13. performanceTest(hashUniq, "hashTable")(data)
  14. performanceTest(sortUniq, "sortUniq")(data)
  15. performanceTest(toSetUniq, "toSetUniq")(data)
  16. performanceTest(indexOfUniq, "indexOfUniq")(data)
  17. performanceTest(doubleLoopUniq, "doubleLoopUniq")(data)
  18. performanceTest(inPlaceUniq, "inPlaceUniq")(data)

結(jié)果如下

</>復(fù)制代碼

  1. hashTable 168ms
  2. sortUniq 332ms
  3. toSetUniq 80ms
  4. indexOfUniq 4280ms
  5. doubleLoopUniq 13303ms
  6. inPlaceUniq 9977ms

延伸思考: 如果數(shù)組內(nèi)的元素是對(duì)象該怎么去重呢?

既然是引用類型,那么不免會(huì)使用到deepEqual,固然這種思路可以解答這道問題,但難免不夠高效。

從上面的測試中也可見通過new Set 和 hashTable 去重是最高效的。
所以毫無疑問,我們要基于這兩種方式去改造,我想用的是hashTable,
另一方面,為了降低深度比較帶來的耗時(shí),我嘗試用JSON.stringify 將引用類型轉(zhuǎn)化為基本類型。

</>復(fù)制代碼

  1. function collectionUniq(collection) {
  2. let hashTable = {};
  3. collection.forEach(item => {
  4. hashTable[JSON.stringify(item)] = true;
  5. })
  6. return Object.keys(hashTable).map(item => JSON.parse(item))
  7. }

那么問題來了,我們都知道對(duì)象的屬性是無序的,假如數(shù)據(jù)是這種情況,那就GG了。

</>復(fù)制代碼

  1. let collection = [ { a: 1, b: 2, c: 3 }, { b: 2, c: 3, a: 1 } ]

有一種toHash的思路,在對(duì)這個(gè)數(shù)組進(jìn)行一次基本的去重之后,為了保證準(zhǔn)確,
先遍歷JSON 字符串 =>
通過 charCodeAt()拿到每個(gè)字符串 的 unicode 編碼 =>
相加得到一個(gè)總數(shù),最后再兩兩進(jìn)行比較,數(shù)值相等的就是重復(fù)的,這樣就達(dá)到去重的效果了。

</>復(fù)制代碼

  1. function toHash(obj) {
  2. let power = 1;
  3. let res = 0;
  4. const string = JSON.stringify(obj, null, 2);
  5. for (let i = 0, l = string.length; i < l; i++) {
  6. switch (string[i]) {
  7. case "{":
  8. power *= 2
  9. break
  10. case "}":
  11. power /= 2
  12. break
  13. case " ":
  14. case "
  15. ":
  16. case "
  17. ":
  18. case "
  19. ":
  20. break
  21. default:
  22. res += string[i].charCodeAt(0) * power
  23. }
  24. }
  25. return res
  26. }

這只是一個(gè)實(shí)現(xiàn)基本的思路,有很大的改進(jìn)空間,為了減少hash碰撞的可能,可以對(duì)一些特殊字符進(jìn)行權(quán)重的增減。

重點(diǎn)是保證碰撞的幾率小到比中大獎(jiǎng)還小就可以了。

2018.2.8
上面是一個(gè)比較清奇的思路,常規(guī)的做法,實(shí)際上還是應(yīng)該從優(yōu)化深度比較的效率入手。
看到一個(gè)很好的實(shí)現(xiàn)思路,是一個(gè)優(yōu)先判錯(cuò)的思路,通過預(yù)設(shè)各種前置條件來避免高代價(jià)的循環(huán),這種思路盡管在數(shù)據(jù)量小的時(shí)候因?yàn)榍爸门袛嗫赡苡幸恍┪⒑跗湮⒌男阅軗p耗,但是數(shù)據(jù)量越大,優(yōu)勢(shì)就越明顯了。感興趣的可以了解下。
https://github.com/epoberezki...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/107306.html

相關(guān)文章

  • JavaScript數(shù)組重的6算法

    摘要:否則存入結(jié)果數(shù)組。否則存入結(jié)果數(shù)組排序后相鄰去除法雖然原生數(shù)組的方法排序結(jié)果不怎么靠譜,但在不注重順序的去重里該缺點(diǎn)毫無影響。實(shí)現(xiàn)思路給傳入數(shù)組排序,排序后相同值相鄰,然后遍歷時(shí)新數(shù)組只加入不與前一值重復(fù)的值。 1.遍歷數(shù)組法 實(shí)現(xiàn)思路:新建一新數(shù)組,遍歷傳入數(shù)組,值不在新數(shù)組就加入該新數(shù)組中;注意點(diǎn):判斷值是否在數(shù)組的方法indexOf是ECMAScript5 方法,IE8以下不支持...

    Panda 評(píng)論0 收藏0
  • JavaScript數(shù)組去重(12方法,史上最全)

    摘要:數(shù)組去重,一般都是在面試的時(shí)候才會(huì)碰到,一般是要求手寫數(shù)組去重方法的代碼。如果是被提問到,數(shù)組去重的方法有哪些你能答出其中的種,面試官很有可能對(duì)你刮目相看。數(shù)組去重的方法一利用去重中最常用不考慮兼容性,這種去重的方法代碼最少。 數(shù)組去重,一般都是在面試的時(shí)候才會(huì)碰到,一般是要求手寫數(shù)組去重方法的代碼。如果是被提問到,數(shù)組去重的方法有哪些?你能答出其中的10種,面試官很有可能對(duì)你刮目相看...

    rozbo 評(píng)論0 收藏0
  • JavaScript數(shù)組去重

    摘要:數(shù)組去重的幾種方法遍歷數(shù)組法這是最簡單的數(shù)組去重方法,實(shí)現(xiàn)思路新建一新數(shù)組,傳入要去重的數(shù)組,遍歷該數(shù)組,若值不在新數(shù)組中則加入該數(shù)組需要注意點(diǎn)判斷值是否在數(shù)組的方法是方法,以下不支持,示例如下對(duì)象鍵值對(duì)法思路新建一對(duì)象以及數(shù)組,遍歷傳入 數(shù)組去重的幾種方法 1.遍歷數(shù)組法 這是最簡單的數(shù)組去重方法,實(shí)現(xiàn)思路:新建一新數(shù)組,傳入要去重的數(shù)組,遍歷該數(shù)組,若值不在新數(shù)組中則加入該數(shù)組;...

    鄒強(qiáng) 評(píng)論0 收藏0
  • [Javascript]數(shù)組重的實(shí)現(xiàn)方式

    摘要:方式使用獲取并刪除刪除數(shù)組的第一個(gè)元素,判斷這個(gè)元素是否還存在于數(shù)組中,如果存在則說明這個(gè)元素的是重復(fù)的如果不存在,進(jìn)行操作方式建立一個(gè)哈希表,通過對(duì)象屬性查詢?nèi)コ貜?fù)元素方式思路和方式類似,但是簡潔很多來源個(gè)人博客 方式1:使用shift()獲取并刪除刪除數(shù)組的第一個(gè)元素,判斷這個(gè)元素是否還存在于數(shù)組中,如果存在則說明這個(gè)元素的是重復(fù)的;如果不存在,進(jìn)行push()操作 functi...

    TZLLOG 評(píng)論0 收藏0
  • JavaScript專題之數(shù)組去重

    摘要:專題系列第三篇,講解各種數(shù)組去重方法,并且跟著寫一個(gè)前言數(shù)組去重方法老生常談,既然是常談,我也來談?wù)劇K愃朴跀?shù)組,但是成員的值都是唯一的,沒有重復(fù)的值。 JavaScript 專題系列第三篇,講解各種數(shù)組去重方法,并且跟著 underscore 寫一個(gè) unique API 前言 數(shù)組去重方法老生常談,既然是常談,我也來談?wù)劇?雙層循環(huán) 也許我們首先想到的是使用 indexOf 來循...

    fsmStudy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<