成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JS專(zhuān)題之?dāng)?shù)組去重

only_do / 3079人閱讀

摘要:將元素作為對(duì)象的鍵,默認(rèn)鍵對(duì)應(yīng)的值為如果對(duì)象中沒(méi)有這個(gè)鍵,則將這個(gè)元素放入結(jié)果數(shù)組中去。

前言

數(shù)組去重在日常開(kāi)發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話(huà)題,所以,我寫(xiě)這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開(kāi)發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。

這次我們來(lái)理一理怎么做數(shù)組去重才能做得最合適,既要考慮兼容性,也要考慮性能和代碼的優(yōu)雅。

我的學(xué)習(xí)路徑是模仿冴羽(github: mqyqingfeng)的學(xué)習(xí)方式,感謝像冴羽這樣優(yōu)秀的人在前面領(lǐng)跑,我不想光看不做,所以多實(shí)踐多輸出,希望未來(lái)能走出我自己的路。

一、入門(mén)方案
function unique(origin) {
    var result = [];
    for(var i = 0; i < origin.length; i++) {
        var arrayItem = origin[i];

        for(var j= 0; j< result.length; j++) {
            var resultItem = result[j];
            
            // 如果在結(jié)果數(shù)組循環(huán)中找到了該元素,則跳出循環(huán),進(jìn)入下一個(gè)源數(shù)組元素的判斷
            if(resultItem === arrayItem) {
                break;
            }
        }
        
        // 如果把結(jié)果數(shù)組循環(huán)完都沒(méi)有找到該元素,就將該元素壓入結(jié)果數(shù)組中
        if(j === result.length) {
            result.push(arrayItem);
        }
    }
    return result;
}

var array = ["a", "b", "c", "1", 0, "c", 1, "", 1, 0];
console.log(unique(array));  // ["a", "b", "c", "1", 0, 1, ""]

以上代碼是最簡(jiǎn)單實(shí)現(xiàn)數(shù)組去重的方式,優(yōu)點(diǎn)在于兼容性極好,缺點(diǎn)就是兩次 for 循環(huán),時(shí)間復(fù)雜度為 O(n^2),性能較差。

二、數(shù)組的 indexOf 屬性

數(shù)組中的 indexOf 屬性是 ES5 的規(guī)范,只有 IE8 及更早版本不支持該方法。相對(duì)來(lái)說(shuō),如果你不需要兼容 IE8 的話(huà),盡量用 indexOf 來(lái)判斷一個(gè)元素是否在數(shù)組中。

function unique(origin){
    var result = [];
    for(var i = 0; i< origin.length; i++) {
        var item = origin[i];
        if(result.indexOf(item) === -1) {
            result.push(item);
        }
    }
    return result;
}
三、數(shù)組的 filter 屬性
數(shù)組的 filter() 方法創(chuàng)建一個(gè)新的數(shù)組,新數(shù)組中的元素是通過(guò)檢查指定數(shù)組中符合條件的所有元素。

filter 的回調(diào)有三個(gè)參數(shù),其中第三個(gè)參數(shù)是當(dāng)前元素屬于的數(shù)組對(duì)象,這樣我們可以繼續(xù)利用 indexOf 屬性啦。

function unique(origin) {
    var result = origin.filter(function (item, index, array){
        // 獲取元素在源數(shù)組的位置,只返回那些索引等于當(dāng)前元素索引的值。
        return array.indexOf(item) === index;
    });
    return result;
}

filter 兼容到 IE9, 這種方法沒(méi)有 for 循環(huán),主要利用了 filter 和 indexOf 屬性,所以代碼相對(duì)比較優(yōu)雅。

四、利用 Object 的 key value
function unique(origin) {
    var result = [];
    var hashTable = {};
    for(var i = 0; i< origin.length; i++) {
        // 如果鍵對(duì)應(yīng)的值,為真,意味著對(duì)象的鍵中已經(jīng)有重復(fù)的鍵了。
        if(!hashTable[origin[i]]) {
        // 將元素作為對(duì)象的鍵,默認(rèn)鍵對(duì)應(yīng)的值為 true, 
            hashTable[origin[i]] = true;
            
            // 如果對(duì)象中沒(méi)有這個(gè)鍵,則將這個(gè)元素放入結(jié)果數(shù)組中去。
            result.push(origin[i]);
        }
    }
    return result;
}

這種方案的事件復(fù)雜度為 O(n), 但是對(duì)象的鍵,默認(rèn)是字符串類(lèi)型,這意味著什么呢,數(shù)字 1 和 字符串 "1",在鍵中是相等的,所以,上面這種方法不適合字符串和數(shù)字混合的去重。

所以我們將元素的類(lèi)型也放入對(duì)象的鍵中:

function unique(origin) {
    var result = [];
    var hashTable = {};
    for(var i = 0; i< origin.length; i++) {
        var current = origin[i];
        // 字符串拼接元素的類(lèi)型和元素
        var key = typeof(current) + current;
        if(!hashTable[key]) {
            hashTable[key] = true;
            result.push(current);
        }
    }
    return result;
}
五、數(shù)組的 sort 方法
function unique(origin) {
    return origin.concat.sort().filter(function(item, index, array) {
        // !index 表示第 0 個(gè)元素應(yīng)該被返回。
        return !index || item !== origin[index-1]
    })
}

function unique(array) {
    array.sort(); // 排序字符串
    array.sort(function(a, b) {
        return a-b; // 排序數(shù)字
    })
    
    for(let i=0; i

sort 方法的優(yōu)點(diǎn)在于利用了排序,返回后一個(gè)和前一個(gè)不相等的元素。比較簡(jiǎn)潔和直觀。缺點(diǎn)在于改變了元素的本來(lái)的排序位置。

六、ES6 Set

ES6 提供了新的數(shù)據(jù)結(jié)構(gòu) Set,它類(lèi)似于數(shù)組,但是成員的值都是唯一的,沒(méi)有重復(fù)的值。向 Set 加入值的時(shí)候,不會(huì)發(fā)生類(lèi)型轉(zhuǎn)變,所以 5 和 "5" 是兩個(gè)不同的值。Set內(nèi)部判斷兩個(gè)值是否相同,用的是類(lèi)似于 "==="的算法,但是區(qū)別是,在set內(nèi)部認(rèn)為NaN 等于 NaN ;

Set 可以轉(zhuǎn)換為數(shù)組,所以很容易實(shí)現(xiàn)去重

function unique(origin) {
    return Array.from(new Set(origin));
}
七、ES6 Map

ES6 新增了 Map 數(shù)據(jù)結(jié)果,通過(guò) has 和 set 方法就能很方便的對(duì)前面的 object key value 方案進(jìn)行優(yōu)化。

function unique(origin){
    const map = new Map()
    return origin.filter((item) => !map.has(item) && map.set(item, true))
}
八、類(lèi)型判斷

一些常見(jiàn)的數(shù)據(jù)類(lèi)型是 ===indexOf 是無(wú)法檢測(cè)的,舉個(gè)例子:

console.log({} === {})  // false;

console.log(NaN === NaN)  // false;

console.log(/a/ === /a/);  // false;

console.log(1 === new String("1"))  // false;

var arr = [NaN];
console.log(arr.indexOf(NaN)); // -1

所以在判斷的時(shí)候,如果數(shù)據(jù)里有 NaN 和對(duì)象時(shí)要避免使用 indexOf===;

前面 Set 那里說(shuō)過(guò)了,所以 Set 方法是可以去重 NaN的。

總結(jié)

數(shù)據(jù)去重在網(wǎng)上已經(jīng)看煩了,但還是想專(zhuān)門(mén)寫(xiě)一篇文章來(lái)實(shí)踐和總結(jié),能在工作中多幾個(gè)思路也是極好的。感謝那些熱愛(ài)分享和喜歡輸出的人。

歡迎關(guān)注我的個(gè)人公眾號(hào)“謝南波”,專(zhuān)注分享原創(chuàng)文章。

掘金專(zhuān)欄 JavaScript 系列文章

JavaScript之變量及作用域

JavaScript之聲明提升

JavaScript之執(zhí)行上下文

JavaScript之變量對(duì)象

JavaScript之原型與原型鏈

JavaScript之作用域鏈

JavaScript之閉包

JavaScript之this

JavaScript之a(chǎn)rguments

JavaScript之按值傳遞

JavaScript之例題中徹底理解this

JavaScript專(zhuān)題之模擬實(shí)現(xiàn)call和apply

JavaScript專(zhuān)題之模擬實(shí)現(xiàn)bind

JavaScript專(zhuān)題之模擬實(shí)現(xiàn)new

JS專(zhuān)題之事件模型

JS專(zhuān)題之事件循環(huán)

JS專(zhuān)題之去抖函數(shù)

JS專(zhuān)題之節(jié)流函數(shù)

JS專(zhuān)題之函數(shù)柯里化

JS專(zhuān)題之?dāng)?shù)組去重

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108916.html

相關(guān)文章

  • JS專(zhuān)題數(shù)組展開(kāi)

    摘要:根據(jù)需求的特點(diǎn),數(shù)組展開(kāi)需要進(jìn)行迭代和遞歸?;卮鹞恼麻_(kāi)頭的問(wèn)題將多重?cái)?shù)組轉(zhuǎn)化成單層數(shù)組的過(guò)程就是數(shù)組展開(kāi),也叫作數(shù)組扁平化一循環(huán)加遞歸最簡(jiǎn)單的思路循環(huán)中判斷,如果子元素是數(shù)組則遞歸。 前言 首先什么是數(shù)組展開(kāi)? 假如現(xiàn)在有這樣一個(gè)需求:將后臺(tái)的一個(gè)多重 List 數(shù)據(jù),展開(kāi)成一個(gè) List 后,并去重后排序; [a, b, [c, d], [[d],e], f] => [a, b, ...

    boredream 評(píng)論0 收藏0
  • JavaScript專(zhuān)題系列文章

    摘要:專(zhuān)題系列共計(jì)篇,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖節(jié)流去重類(lèi)型判斷拷貝最值扁平柯里遞歸亂序排序等,特點(diǎn)是研究專(zhuān)題之函數(shù)組合專(zhuān)題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實(shí)現(xiàn)模式需求我們需要寫(xiě)一個(gè)函數(shù),輸入,返回。 JavaScript 專(zhuān)題之從零實(shí)現(xiàn) jQuery 的 extend JavaScritp 專(zhuān)題系列第七篇,講解如何從零實(shí)現(xiàn)一個(gè) jQuery 的 ext...

    Maxiye 評(píng)論0 收藏0
  • JS數(shù)組專(zhuān)題2?? ? 數(shù)組去重

    距離上次發(fā)文,已經(jīng)有一段時(shí)間了,最近工作比較忙,這不眼看快雙十一了,就相當(dāng)于給大家一些福利吧! showImg(https://segmentfault.com/img/remote/1460000016538082?w=250&h=250); 一、什么是數(shù)組去重 簡(jiǎn)單說(shuō)就是把數(shù)組中重復(fù)的項(xiàng)刪除掉,你 GET 到了嗎 ?下面我將簡(jiǎn)單介紹下幾種基本的方法及其優(yōu)缺點(diǎn)。 二、方法匯總 兩層循環(huán) 無(wú)相同...

    tunny 評(píng)論0 收藏0
  • JavaScript專(zhuān)題系列20篇正式完結(jié)!

    摘要:寫(xiě)在前面專(zhuān)題系列是我寫(xiě)的第二個(gè)系列,第一個(gè)系列是深入系列。專(zhuān)題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點(diǎn)贊,鼓勵(lì)指正。 寫(xiě)在前面 JavaScript 專(zhuān)題系列是我寫(xiě)的第二個(gè)系列,第一個(gè)系列是 JavaScript 深入系列。 JavaScript 專(zhuān)題系列共計(jì) 20 篇,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖、節(jié)流、去重、類(lèi)型判斷、拷貝、最值、扁平、柯里...

    sixleaves 評(píng)論0 收藏0
  • JavaScript專(zhuān)題數(shù)組去重

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

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

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

0條評(píng)論

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