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

資訊專欄INFORMATION COLUMN

JavaScript數(shù)組方法之?dāng)?shù)組去重方法

CarlBenjamin / 1889人閱讀

摘要:工作過(guò)程中經(jīng)常會(huì)用到數(shù)組去重,用到的時(shí)候往往一時(shí)想不到好方法,所以這里來(lái)總結(jié)一下去重方法。和方法分別為添加成員方法和得到鍵值方法。因此,利用方法也可以實(shí)現(xiàn)數(shù)組的去重。

工作過(guò)程中經(jīng)常會(huì)用到數(shù)組去重,用到的時(shí)候往往一時(shí)想不到好方法,所以這里來(lái)總結(jié)一下去重方法。
使用es6去重代碼很簡(jiǎn)單,而且ES6已經(jīng)相當(dāng)普及了。所以先來(lái)介紹一下es6中的方法。

1.ES6中Map結(jié)構(gòu)方法
function unique (arr) {
  const seen = new Map()
  return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}
let arr = [1, 2, 1, 3, "1", NaN, NaN, null, null, undefined, undefined, {}, {}];
console.log(uniMap(arr));  //[ 1, 2, 3, "1", NaN, null, undefined, {}, {} ]

Map是es6中新增的數(shù)據(jù)結(jié)構(gòu),它類似于對(duì)象,也是鍵值對(duì)的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對(duì)象)都可以當(dāng)作鍵。也就是說(shuō),Object 結(jié)構(gòu)提供了“字符串—值”的對(duì)應(yīng),Map 結(jié)構(gòu)提供了“值—值”的對(duì)應(yīng),是一種更完善的 Hash 結(jié)構(gòu)實(shí)現(xiàn)。
Map的has方法用于判斷map是否含有該鍵。setget 方法分別為添加成員方法和得到鍵值方法。
上述方法一方面利用了map的has和set方法,一方面利用了數(shù)組的 filter方法,返回結(jié)果為真的元素組成的數(shù)組。
注意
Map 的鍵實(shí)際上是跟內(nèi)存地址綁定的,只要內(nèi)存地址不一樣,就視為兩個(gè)鍵。這句話不好理解的話,可以這樣說(shuō)如果 Map 的鍵是一個(gè)簡(jiǎn)單類型的值(數(shù)字、字符串、布爾值),則只要兩個(gè)值嚴(yán)格相等,Map 將其視為一個(gè)鍵,比如0和-0就是一個(gè)鍵,布爾值true和字符串true則是兩個(gè)不同的鍵, 對(duì)象是不同的鍵;另外,undefined和null也是兩個(gè)不同的鍵。雖然NaN不嚴(yán)格相等于自身,但 Map 將其視為同一個(gè)鍵

2. ES6中數(shù)組Set結(jié)構(gòu)方法
function uniMap (arr) {
  return [...new Set(arr)];
}
let arr = [1, 2, 1, 3, "1", NaN, NaN, null, null, undefined, undefined, {}, {}];
console.log(uniMap(arr));  // [ 1, 2, 3, "1", NaN, null, undefined, {}, {} ]

Set 也是ES6 提供的新的數(shù)據(jù)結(jié)構(gòu)。它類似于數(shù)組,但是成員的值都是唯一的,沒(méi)有重復(fù)的值。
Set 本身是一個(gè)構(gòu)造函數(shù),用來(lái)生成Set數(shù)據(jù)結(jié)構(gòu),它也接受一個(gè)數(shù)組或具有iterator接口的數(shù)據(jù)結(jié)構(gòu)作為參數(shù)初始化。上述代碼中就是利用了這個(gè)特性來(lái)實(shí)現(xiàn)對(duì)數(shù)組的去重。
Set 具有add方法來(lái)添加某個(gè)值,返回set結(jié)構(gòu)本身。因此,利用add方法也可以實(shí)現(xiàn)數(shù)組的去重。例如:

const s = new Set();
function uniMap(arr)  {
    arr.forEach( item => s.add(item));
    return [...s];  // [ 1, 2, 3, "1" ]
}
// main
let arr = [1, 2, 1, 3, "1", 2, 2, 2];
console.log(uniMap(arr));

Array.from也是ES6中的新方法可以將 Set 結(jié)構(gòu)轉(zhuǎn)為數(shù)組。這就引出第三種使用set的數(shù)組去重方法:

// set3
function uniMap(arr) {
    return Array.from(new Set(arr));
}
let arr = [1, 2, 1, 3, "1", NaN, NaN, null, null, undefined, undefined, {}, {}];
console.log(uniMap(arr));  // [ 1, 2, 3, "1", NaN, null, undefined, {}, {} ]

注意
Set 內(nèi)部判斷兩個(gè)值是否不同,使用的算法叫做“Same-value-zero equality”,它類似于精確相等運(yùn)算符(===),所以上述結(jié)果中 1 和 "1" 認(rèn)為是不相同的,都被保留下來(lái),主要的區(qū)別是NaN等于自身,而精確相等運(yùn)算符認(rèn)為NaN不等于自身。另外,兩個(gè)對(duì)象總是不相等的。

3. 基本雙重循環(huán)
function uniMap(arr) {
    let res = [];
    for(let i = 0, arrLen = arr.length; i < arrLen; i += 1) {
        let j = 0, resLen = res.length;
        for(; j < resLen; j +=1) {
            if(arr[i] === res[j]) {
                break;
            }
        }
        if( j === resLen) {
            res.push(arr[i]);
        }
    }
    return res;  
}
// main
let arr = [1, 2, 1, 3, "1", 2, 2, 2];
console.log(uniMap(arr)); // [ 1, 2, 3, "1" ]
arr = [1, 2, 1, 3, "1", NaN, NaN, null, null, undefined, undefined, {}, {}];
console.log(uniMap(arr)); //[ 1, 2, 3, "1", NaN, NaN, null, undefined, {}, {} ]

我們使用循環(huán)嵌套,最外層循環(huán) array,里面循環(huán) res,如果 array[i] 的值跟 res[j] 的值相等,就跳出循環(huán),如果都不等于,說(shuō)明元素是唯一的,這時(shí)候 j 的值就會(huì)等于 res 的長(zhǎng)度,根據(jù)這個(gè)特點(diǎn)進(jìn)行判斷,將值添加進(jìn) res。
這個(gè)是最基本的方法,但是第一次寫還真犯了錯(cuò),無(wú)法去重。代碼是這樣的:

function uniMap(arr) {
    let res = [];
    for(let i = 0, arrLen = arr.length; i < arrLen; i += 1) {
        let j = 0, resLen = res.length;
        for(; j < resLen; j +=1) {
            if(arr[i] === res[j]) {
                break;
            }
            res.push(arr[i]);
        }
    }
    return res;   // []
}
// main
let arr = [1, 2, 1, 3, "1", 2, 2, 2];
console.log(uniMap(arr));

和上面代碼相比,就是res.push(arr[i]);放在了內(nèi)循環(huán)里,少了 j === resLen的判斷,就得到了空數(shù)組。原因是 初始的時(shí)候res.length = 0,不會(huì)進(jìn)到內(nèi)循環(huán),所以res始終為空。果然眼高手低啊~

4. indexOf方法優(yōu)化雙重循環(huán)中的內(nèi)部循環(huán)
// 雙重循環(huán)2 
function uniMap(arr) {
    let res = [];
    for(let i = 0, arrLen = arr.length; i < arrLen; i += 1) {
        if( res.indexOf(arr[i]) === -1) {
            res.push(arr[i]);
        }
    }
    return res;    
}
// main
let arr = [1, 2, 1, 3, "1", 2, 2, 2];
console.log(uniMap(arr)); // [ 1, 2, 3, "1" ]
arr = [1, 2, 1, 3, "1", NaN, NaN, null, null, undefined, undefined, {}, {}];
console.log(uniMap(arr)); // [ 1, 2, 3, "1", NaN, NaN, null, undefined, {}, {} ]
5. filter方法優(yōu)化雙重循環(huán)中的外層循環(huán)
// filter方法
function uniMap(arr) {
    let res = [];
    return res = arr.filter( (item , index) => {
        return arr.indexOf(item) === index;
    })   //[ 1, 2, 3, "1", null, undefined ]
}
// main
let arr = [1, 2, 1, 3, "1", NaN, NaN, null, null, undefined, undefined, {}, {}];
console.log(uniMap(arr)); // [ 1, 2, 3, "1", null, undefined, {}, {} ]

此處的filter方法可以和方法3,4排列組合用~~其實(shí)方法1也利用了filter方法(filter人氣高啊)filter方法原理已經(jīng)說(shuō)過(guò),忘記的往上翻~

6. Object 方法
// object
function uniMap(arr) {
    let obj = {};
    return arr.filter( item => {
        return obj.hasOwnProperty(item) ? false : (obj[item] = true);
    })  
}
// main
let arr = [1, 2, 1, 3, "1", 2, 2, 2, NaN, NaN, null, null, undefined, undefined];
console.log(uniMap(arr)); // [ 1, 2, 3, NaN, null, undefined ]

上述代碼原理是利用一個(gè)空的 Object 對(duì)象,我們把數(shù)組的值存成 Object 的 key 值,比如 Object[value1] = true,在判斷另一個(gè)值的時(shí)候,如果 Object[value2]存在的話,就說(shuō)明該值是重復(fù)的。從結(jié)果可以看到,他把數(shù)字 1 和字符串 "1"當(dāng)成了同一個(gè)字符,因?yàn)閷?duì)象的key值均是字符串,數(shù)字1被轉(zhuǎn)換為字符串了,因此該方法適用于你想把數(shù)字和字符串去重的場(chǎng)合。

特殊數(shù)據(jù)結(jié)構(gòu)的去重判斷

去重的方法就到此結(jié)束了,然而根據(jù)上面的結(jié)果可以看到,對(duì)于特殊的數(shù)據(jù)類型比如:null、undefined、NaN、對(duì)象等,不同的去重方法其實(shí)結(jié)果是不同的。那么下面給個(gè)總結(jié)和分析。
對(duì)于例子中的這樣一個(gè)數(shù)組:
[1, 2, 1, 3, "1", 2, 2, 2, NaN, NaN, null, null, undefined, undefined];

方法 結(jié)果 說(shuō)明
1.Map [ 1, 2, 3, "1", NaN, null, undefined, {}, {} ] 對(duì)象不去重
2.Set [ 1, 2, 3, "1", NaN, null, undefined, {}, {} ] 對(duì)象不去重
3.雙重循環(huán) [ 1, 2, 3, "1", NaN, NaN, null, undefined, {}, {} ] 對(duì)象和NaN都不去重
4.內(nèi)層index [ 1, 2, 3, "1", NaN, NaN, null, undefined, {}, {} ] 對(duì)象和NaN不去重
5.外層filter [ 1, 2, 3, "1", null, undefined, {}, {} ] 對(duì)象不去重NaN被忽略掉
6.Object方法 [ 1, 2, 3, NaN, null, undefined ] 數(shù)字和字符串去重,對(duì)象被忽略

之所以出現(xiàn)上面的結(jié)果,先看一下幾個(gè)判斷:

console.log(null === null);  // true
console.log(undefined === undefined); // true
console.log(NaN === NaN);  // false
console.log({} === {});  // false

再結(jié)合 indexOf 是使用 === 判斷,以及set map 也使用 === 判斷但是認(rèn)為 NaN 和 NaN 相等,便可以分析出來(lái)。

注意
對(duì)于數(shù)組元素和去重不是上述類型和結(jié)果的,那么針對(duì)你想要的去重去靈活修改代碼,不可以生搬硬套~~

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

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

相關(guān)文章

  • JS專題數(shù)組去重

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

    only_do 評(píng)論0 收藏0
  • 也談面試必備問(wèn)題 JavaScript 數(shù)組去重

    摘要:而數(shù)組元素去重是基于運(yùn)算符的。而如果有迭代函數(shù),則計(jì)算傳入迭代函數(shù)后的值,對(duì)值去重,調(diào)用方法,而該方法的核心就是調(diào)用方法,和我們上面說(shuō)的方法一異曲同工。 Why underscore (覺(jué)得這部分眼熟的可以直接跳到下一段了...) 最近開(kāi)始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計(jì)劃中。 閱讀一些著名框架類庫(kù)的源碼,就好像...

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

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

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

    摘要:專題系列共計(jì)篇,主要研究日常開(kāi)發(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
  • JavaScript專題系列20篇正式完結(jié)!

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

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

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

0條評(píng)論

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