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

資訊專欄INFORMATION COLUMN

JavaScript系列--八種【數(shù)組去重】方法的總結(jié)

Xufc / 2373人閱讀

摘要:缺點(diǎn)不兼容以下瀏覽器七高階函數(shù)方法用來(lái)判斷一個(gè)數(shù)組是否包含一個(gè)指定的值,根據(jù)情況,如果包含則返回,否則返回。方法六高階函數(shù)優(yōu)點(diǎn)高階函數(shù)的高級(jí)用法。

一、前言

數(shù)組去重是一個(gè)老生常談的問(wèn)題,但是有時(shí)候會(huì)彈出點(diǎn)其他東西。

二、雙重循環(huán)

這個(gè)方法是最常見的,最原始的方法。

// 方法一:雙重循環(huán)
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    // res 存結(jié)果
    var res = [];
    for(var i = 0, length = arr.length; i < length; i++){
        for(var j = 0, length2 = res.length; j < length2; j++){
            if(arr[i] === res[j]){
                break;
            }
        }
        if(j == length2){
            res.push(arr[i])
        }
    }
    return res;
}

unique(array);  //[1, "1", "2", 2]

思路:雙層循環(huán)方法,使用的是循環(huán)嵌套,外層是arr,里層是res,如果arr[i]的值等于res[j]的值,則跳出當(dāng)前循環(huán),如果都不等于,說(shuō)明元素唯一,這時(shí)候j的值等于res的長(zhǎng)度,根據(jù)這個(gè)判斷,將值添加res中。

優(yōu)點(diǎn):兼容性好

缺點(diǎn):時(shí)間復(fù)雜度o(n2)

三、indexOf方法

思路:使用indexOf簡(jiǎn)化內(nèi)層循環(huán)。

// 方法二:indexOf簡(jiǎn)化內(nèi)層循環(huán)
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    // res 存結(jié)果
    var res = [];
    for(var i = 0, length = arr.length; i < length; i++){
       var current = arr[i];
       if(res.indexOf(current) === -1){
           res.push(current);
       }
    }
    return res;
}

unique(array);   //[1, "1", "2", 2]

優(yōu)點(diǎn):時(shí)間復(fù)雜度降低

缺點(diǎn):有的瀏覽器不支持indexOf方法,時(shí)間復(fù)雜度o(n2)

四、排序后去重

思路:使用快排sort將數(shù)組排序,這樣相同的值會(huì)被排在一起,只需要判斷當(dāng)前元素與上一個(gè)元素是否相同,相同說(shuō)明重復(fù),不同就添加進(jìn)res中。

// 方法三:排序后去重
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    // res 存結(jié)果
    var res = [];
    var sortedArray = arr.concat().sort();
    console.log(sortedArray, "-=-=-=-=-=-=")
    var current;
    for(var i = 0, length = sortedArray.length; i < length; i++){
        // 如果是第一個(gè)元素 或者是相鄰元素不相同
       if(!i || current !== sortedArray[i]){
           res.push(sortedArray[i]);
       }
       current = sortedArray[i];
    }
    return res;
}

unique(array);   //[1, "1", 1, "2", 2]

優(yōu)點(diǎn):已經(jīng)排好序的數(shù)組去重,這種方法效率高于使用 indexOf,時(shí)間復(fù)雜度o(n)

缺點(diǎn):已經(jīng)修改數(shù)組的順序,同時(shí)存在去重不徹底

注意:sort函數(shù)默認(rèn)排序是 Unicode,srot方法默認(rèn)可是能給字母實(shí)現(xiàn)排序。突然發(fā)現(xiàn)了sort在排序的時(shí)候存在一個(gè)隱式轉(zhuǎn)換,會(huì)把要排序的對(duì)象轉(zhuǎn)換成字符串,sort排序的時(shí)候1和"1"是相同的,然后根據(jù)unicode比較大小,所以出現(xiàn)了[1, "1", 1, "2", 2]這種情況。

注意:數(shù)組進(jìn)行了 array.concat()操作之后,其實(shí)是復(fù)制出來(lái)一份原有的數(shù)組,復(fù)制出來(lái)的新數(shù)組不會(huì)影響到原有數(shù)組。

五、使用ES5的filter

思路:使用filter簡(jiǎn)化外層循環(huán)

1、使用indexOf簡(jiǎn)化內(nèi)層循環(huán)
// 方法四:filter + indexOf
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    // res 存結(jié)果
    var res = arr.filter(function(item, index, arr){
        return arr.indexOf(item) === index;
    })
    return res;
}

unique(array);   //[1, "1", "2", 2]
2、排序去重的方法
// 方法四:filter + sort
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    // res 存結(jié)果
    var res = arr.concat().sort().filter(function(item, index, arr){
        return !index ||  item !==arr[index -1]
    })
    return res;
}

unique(array);   //[1, "1", 1, "2", 2]

上面已經(jīng)講到了sort排序時(shí)候存在一個(gè)隱式轉(zhuǎn)換。

優(yōu)點(diǎn):很簡(jiǎn)潔,思維也比較巧妙,直觀易懂,使用filter簡(jiǎn)化外層循環(huán)

缺點(diǎn):不支持 IE9 以下的瀏覽器,時(shí)間復(fù)雜度o(n*2)

六、Object鍵值對(duì)的問(wèn)題

思路:利用一個(gè)空的Object對(duì)象,把數(shù)組的值存成Object的key,比如就是Object[value] = true;循環(huán)判斷的時(shí)候,如果Object[value]存在,說(shuō)明這個(gè)值重復(fù)了。

// 方法五:Object鍵值對(duì)
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    // obj 存對(duì)象
    var obj= {};
    var res = arr.filter(function(item, index, arr){
        if(obj.hasOwnProperty(item)) return false;
        else {
            return obj[item] = true;
        }
    })
    return res;
}

unique(array);   //[1, "2"]

然后我們發(fā)現(xiàn)1和"1"是不同的,但是這種方法會(huì)判斷為是同一個(gè)值,因?yàn)殒I值對(duì)中只能是字符串,會(huì)進(jìn)行一個(gè)隱式轉(zhuǎn)換。和sort排序時(shí)候的轉(zhuǎn)換是一樣的,可以通過(guò)typeof item+ item,拼成字符串作為key的值避免這個(gè)問(wèn)題

// 優(yōu)化
function unique(arr){
    // obj 存對(duì)象
    var obj= {};
    var res = arr.filter(function(item, index, arr){
        if(obj.hasOwnProperty(typeof item + item)) return false;
        else {
            return obj[typeof item + item] = true;
        }
    })
    return res;
}

unique(array);   //[1, "1", "2", 2]

優(yōu)點(diǎn):hasOwnProperty是對(duì)象的屬性存在性檢查方法。對(duì)象的屬性可以基于hash表實(shí)現(xiàn),因此對(duì)屬性的方法的時(shí)間復(fù)雜度達(dá)到O(1);filter是數(shù)組迭代的方法,內(nèi)部是一個(gè)for循環(huán),復(fù)雜度O(n)??偟臅r(shí)間復(fù)雜度O(n)。

缺點(diǎn):不兼容IE9以下瀏覽器

七、reduce高階函數(shù)

includes() 方法用來(lái)判斷一個(gè)數(shù)組是否包含一個(gè)指定的值,根據(jù)情況,如果包含則返回 true,否則返回false。

// 方法六:reduce高階函數(shù)
var array = [1,1,"1","2","1",1,2]
function unique(arr){
    let newArr = arr.reduce((pre,cur)=>{
        if(!pre.includes(cur)){
            return pre.concat(cur)
        }else{
            return pre
        }
    },[]);
    return newArr;
}
console.log(unique(array));// [1, "1", "2", 2]

優(yōu)點(diǎn):高階函數(shù)的高級(jí)用法。

缺點(diǎn):兼容性問(wèn)題,對(duì)象數(shù)組不能使用includes方法來(lái)檢測(cè)。includes區(qū)分大小寫

八、ES6的Set數(shù)據(jù)結(jié)構(gòu)

只能說(shuō)ES6標(biāo)準(zhǔn)越來(lái)越好,可以使用Set數(shù)據(jù)結(jié)構(gòu),ES6中提供了set數(shù)據(jù)結(jié)構(gòu),類似于數(shù)組,成員值都是唯一的,沒(méi)有重復(fù)的。

// 方法七:ES6的set
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    return Array.from(new Set(arr));
}

unique(array);   //[1, "1", "2", 2]

還可以用擴(kuò)展運(yùn)算符...

// 優(yōu)化
var array = [1,1,"1","2","1",1,2]

function unique(arr){
    return  [...new Set(arr)];
}

unique(array);   //[1, "1", "2", 2]

再寫簡(jiǎn)單點(diǎn)

// 再優(yōu)化
var array = [1,1,"1","2","1",1,2]

const unique = arr => [...new Set(arr)];

unique(array);   //[1, "1", "2", 2]

優(yōu)點(diǎn):ES6語(yǔ)法簡(jiǎn)單高效。

缺點(diǎn):兼容性問(wèn)題,加上使用babel編譯不是問(wèn)題。

九、ES6的Map數(shù)據(jù)結(jié)構(gòu)
// 方法八:ES6的Map + filter
var array = [1,1,"1","2","1",1,2];

function unique(arr){
    var current = new Map();
    var res = arr.filter(function(item, index, arr){
        if(current.has(item)){
            return false;
        }else{
            return current.set(item, 1);
        }
    })
    return res;
}

unique(array);   //[1, "1", "2", 2]

思路:使用map的方法set和has,用has方法來(lái)判斷是否存在這個(gè)key,如果沒(méi)有值將map中存一個(gè)key-value。

注意:最新的ES6規(guī)范引入了新的數(shù)據(jù)類型Map,為了解決對(duì)象中的鍵只能是字符串的問(wèn)題,其實(shí)其他基本數(shù)據(jù)類型是可以作為鍵的。

優(yōu)點(diǎn):ES6語(yǔ)法簡(jiǎn)單高效。

缺點(diǎn):兼容性問(wèn)題,加上使用babel編譯不是問(wèn)題。

十、特殊數(shù)據(jù)類型比較
var str1 = "1";
var str2 = new String("1");

console.log(str1 == str2); // true
console.log(str1 === str2); // false

console.log(null == null); // true
console.log(null === null); // true

console.log(undefined == undefined); // true
console.log(undefined === undefined); // true

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

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

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

看個(gè)栗子1

var arr = [1, 2, NaN];
arr.indexOf(NaN); // -1

原因:indexOf底層還是使用 === 來(lái)進(jìn)行判斷的,因?yàn)镹AN === NAN結(jié)果是false,使用indexOf還是查不到NAN這個(gè)元素。

再看個(gè)栗子2

function unique(array) {
   return Array.from(new Set(array));
}
console.log(unique([NaN, NaN])) // [NaN]

Set中,NAN === NAN是false,但是這兩個(gè)元素是重復(fù)的

十一、后話

在對(duì)數(shù)組去重的性能進(jìn)行優(yōu)化,然后想了半天也只寫出來(lái)了Object鍵值對(duì)的性能,找不到其他既能判斷引用類型,性能又穩(wěn)定在n^2之內(nèi)的方式?

自己回答一下:

目前時(shí)間復(fù)雜度到O(n)的方法:

(1)Object鍵值對(duì),實(shí)質(zhì)是hasOwnProperty的hash表。

(2)ES6的set,map的數(shù)據(jù)結(jié)構(gòu)

(3)reduce高階函數(shù)

【注:我是saucxs,也叫songEagle,松寶寫代碼,文章首發(fā)于sau交流學(xué)習(xí)社區(qū)(https://www.mwcxs.top),關(guān)注我們每天閱讀更多精彩內(nèi)容】

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

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

相關(guān)文章

  • JavaScript專題系列20篇正式完結(jié)!

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

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

    摘要:將元素作為對(duì)象的鍵,默認(rèn)鍵對(duì)應(yīng)的值為如果對(duì)象中沒(méi)有這個(gè)鍵,則將這個(gè)元素放入結(jié)果數(shù)組中去。 前言 數(shù)組去重在日常開發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話題,所以,我寫這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。 這次我們來(lái)理一理怎么做數(shù)組去重才能做得最合適,既要考慮兼容性,...

    only_do 評(píng)論0 收藏0
  • 8種常用數(shù)組去重方法

    摘要:種常用數(shù)組去重第一種兩個(gè)循環(huán)思路新建一個(gè)為空的結(jié)果數(shù)組外層遍歷原數(shù)組,內(nèi)層循環(huán)遍歷返回?cái)?shù)組判斷內(nèi)層循環(huán)數(shù)組當(dāng)前元素和外層數(shù)組元素的值是否相等,是退出內(nèi)層循環(huán)經(jīng)過(guò)第二部后,此時(shí)內(nèi)層循環(huán)數(shù)組的索引值和返回?cái)?shù)組的長(zhǎng)度正好相等,外層數(shù)組元素也是唯一 8 種常用數(shù)組去重 第一種 【兩個(gè) for 循環(huán)】 思路: 新建一個(gè)為空的結(jié)果數(shù)組 外層 for 遍歷原數(shù)組,內(nèi)層循環(huán)遍歷返回?cái)?shù)組 判斷內(nèi)層循環(huán)...

    vibiu 評(píng)論0 收藏0
  • JS程序

    摘要:設(shè)計(jì)模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時(shí)候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計(jì)模式必須要先搞懂面向?qū)ο缶幊?,否則只會(huì)讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識(shí)只有分享才有存在的意義。 是時(shí)候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...

    melody_lql 評(píng)論0 收藏0
  • JavaScript專題系列文章

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

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

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

0條評(píng)論

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