JavaScript怎么實(shí)現(xiàn)數(shù)組去重

這篇“JavaScript怎么實(shí)現(xiàn)數(shù)組去重”文章,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要參考一下,對(duì)于“JavaScript怎么實(shí)現(xiàn)數(shù)組去重”,小編整理了以下知識(shí)點(diǎn),請(qǐng)大家跟著小編的步伐一步一步的慢慢理解,接下來(lái)就讓我們進(jìn)入主題吧。

成都創(chuàng)新互聯(lián)主營(yíng)陽(yáng)泉網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app軟件開(kāi)發(fā),陽(yáng)泉h5微信小程序搭建,陽(yáng)泉網(wǎng)站營(yíng)銷(xiāo)推廣歡迎陽(yáng)泉等地區(qū)企業(yè)咨詢(xún)

JavaScript的特點(diǎn)

1.JavaScript主要用來(lái)向HTML頁(yè)面添加交互行為。 2.JavaScript可以直接嵌入到HTML頁(yè)面,但寫(xiě)成單獨(dú)的js文件有利于結(jié)構(gòu)和行為的分離。 3.JavaScript具有跨平臺(tái)特性,在絕大多數(shù)瀏覽器的支持下,可以在多種平臺(tái)下運(yùn)行。

一、雙層循環(huán)

const unique = (arr)=>{
    for(let i = 0; i < arr.length; i++){
        for(let j = i + 1; j < arr.length; j++){
            if(arr[i] === arr[j]){
                arr.splice(j, 1); // 移除重復(fù)元素
                j--; // 修正下標(biāo)
            }
        }
    }
    return arr;};const unique = (arr)=>{
    var arr = [1, '1', '1', 1, 2, true, false, true, 3, 2, 2, 1];
    var newArr = [];
    for(let i = 0; i < arr.length; i++){
        for(var j = 0; j < newArr.length; j++){ // 注意var聲明的j
            if(arr[i] === newArr[j]) break; // 新數(shù)組已存在當(dāng)前值
        }
        if(j === newArr.length){ // 此時(shí)j和newArr長(zhǎng)度相等,沒(méi)有被中斷
            newArr.push(arr[i]);
        }
    }
    return newArr;}unique([1, '1', '1', 1, 2, true, false, true, 3, 2, 2, 1]); // [ 1, '1', 2, true, false, 3 ]

核心點(diǎn):

  • 時(shí)間復(fù)雜度:O(n^2)

  • 上面的兩種方法都是兩次循環(huán)遍歷,處理方式略有不同

  • 上述實(shí)現(xiàn)方式確實(shí)不是最佳選擇,但它勝在兼容性好啊~

二、indexOf和includes

2.1 indexOf簡(jiǎn)化一層循環(huán)判斷

核心點(diǎn):

  • 如果需要返回原數(shù)組,則可以在indexOf方法找到重復(fù)項(xiàng)時(shí)(不等于它首次出現(xiàn)的位置)時(shí)利用splice移除

  • indexOf:返回在數(shù)組中可以找到一個(gè)給定元素的第一個(gè)索引,如果不存在,則返回-1。

  • indexOf(ele, fromIndex)

    • ele:要查找的元素

    • fromIndex:查找元素的起始位置,默認(rèn)為0,允許負(fù)數(shù),-2表示從倒數(shù)第二個(gè)元素開(kāi)始查找

    • 返回一個(gè)下標(biāo)(number)

代碼:

const unique = (arr) => {
    var res = [];
    for (let i = 0; i < arr.length; i++){
        if(res.indexOf(arr[i]) === -1 ){
            res.push(arr[i]);
        }
    }
    return res;}
2.2 includes簡(jiǎn)化一層循環(huán)判斷

核心點(diǎn):

  • 具體的是要返回原數(shù)組還是新數(shù)組大家可以自行組合~

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

  • includes(ele, fromIndex)

    • ele:要查找的元素

    • fromIndex:指定索引處開(kāi)始查找。默認(rèn)為 0,如果為負(fù)值,從末尾開(kāi)始往前跳 fromIndex 的絕對(duì)值個(gè)索引。。

    • 返回結(jié)果(bool)

代碼:

const unique = (arr) => {
    var res = [];
    for (let i = 0; i < arr.length; i++){
        if(!res.includes(arr[i])){
            res.push(arr[i]);
        }
    }
    return res;}
2.3 indexOf和includes對(duì)于當(dāng)前場(chǎng)景的選擇

在這里我們推薦使用includes來(lái)查找元素:

返回值可以直接作為if的條件語(yǔ)句,簡(jiǎn)潔

if(res.indexOf(arr[i]) !== -1 ){ todo }// orif(res.includes(arr[i])){ todo }

識(shí)別NaN

如果數(shù)組中有NaN,你又正好需要判斷數(shù)組是否有存在NaN,這時(shí)你使用indexOf是無(wú)法判斷的,你必須使用includes這個(gè)方法。

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

識(shí)別undefined

如果數(shù)組中有undefined值,includes會(huì)認(rèn)為空的值是undefined,而indexOf不會(huì)。

var arr = new Array(3);console.log(arr.indexOf(undefined)); //-1console.log(arr.includes(undefined)) //true

三、排序去重

核心點(diǎn):

  • 數(shù)組排序后,相同的元素會(huì)相鄰,所以如果當(dāng)前元素與它的相鄰元素不同,就存入到新數(shù)組中;

  • 相比于indexOf,只需要一層循環(huán);

  • concat會(huì)拼接數(shù)組,并返回新數(shù)組;

  • sort()排序是通過(guò)按照轉(zhuǎn)換為的字符串的各個(gè)字符的Unicode位點(diǎn)進(jìn)行排序。所以很難保證它的準(zhǔn)確性;

代碼:

var arr = [1, 1, '1'];function unique(arr) {
    var res = [];
    var sortedArr = arr.concat().sort();
    var last;
    for (var i = 0; i < sortedArr.length ; i++) {
        // 如果是第一個(gè)元素或者相鄰的元素不相同
        if (!i || last !== sortedArr[i]) {
            res.push(sortedArr[i])
        }
        last = sortedArr[i]; // 記錄上一個(gè)值
    }
    return res;}console.log(unique(array));

四、filter

核心點(diǎn):

  • filter:方法創(chuàng)建一個(gè)新數(shù)組, 其包含通過(guò)所提供函數(shù)實(shí)現(xiàn)的測(cè)試的所有元素(返回測(cè)試函數(shù)成立的元素)

  • filter(callback, thisArg)

    • callback接受三個(gè)參數(shù):element-當(dāng)前正在處理的元素,index-當(dāng)前元素索引,array-調(diào)用了filter的數(shù)組本身

    • thisArg:執(zhí)行 callback 時(shí),用于 this 的值。
      利用filter我們可以在代碼層面簡(jiǎn)化一下外層循環(huán):

代碼:

var arr = [1, 2, 1, 1, '1'];const unique = function (arr) {
    var res = arr.filter(function(item, index, arr){
        return arr.indexOf(item) === index;
    })
    return res;}console.log(unique(arr)); // [ 1, 2, '1' ]

結(jié)合排序的思路:

var arr = [1, 2, 1, 1, '1'];const unique = function (arr) {
    return arr.concat().sort().filter(function(item, index, arr){
        return !index || item !== arr[index - 1]
    })}console.log(unique(arr));

五、鍵值對(duì)(key-value)

前面提到的幾種方式總結(jié)下來(lái)大致分為

  1. 非排序數(shù)組,兩次遍歷判斷(遍歷、查詢(xún))

  2. 排序數(shù)組,相鄰元素比較

我們?cè)偬岢鲆环N方式,利用Object對(duì)象 key-value的方式,來(lái)統(tǒng)計(jì)數(shù)組中元素出現(xiàn)的個(gè)數(shù),初步判斷邏輯也有兩種

[1,1,1,2,2,3,'3']舉例:

  1. 統(tǒng)計(jì)每個(gè)元素出現(xiàn)的次數(shù),obj:{1: 3, 2: 2, 3: 3}, 返回這個(gè)objkey而不管他們的value

  2. 只元素首次出現(xiàn),再次出現(xiàn)則證明他是重復(fù)元素

5.1 統(tǒng)計(jì)次數(shù)
var arr = [1, 2, 1, 1, '1', 3, 3];const unique = function(arr) {
    var obj = {};
    var res = [];
    arr.forEach(item => {
        if (!obj[item]) {
            obj[item] = true;
            res.push(item);
        }
    });
    return res;}console.log(unique(arr)); // [1, 2, 3]
5.2 結(jié)合filter
var arr = [1, 2, 1, 1, '1'];const unique = function(arr) {
    var obj = {};
    return arr.filter(function(item, index, arr){
        return obj.hasOwnProperty(item) ? false : (obj[item] = true)
    })}console.log(unique(arr)); // [1, 2]
5.3 key: value存在的問(wèn)題

對(duì)象的屬性是字符串類(lèi)型的,即本身數(shù)字1字符串‘1’是不同的,但保存到對(duì)象中時(shí)會(huì)發(fā)生隱式類(lèi)型轉(zhuǎn)換,導(dǎo)致去重存在一定的隱患。

考慮到string和number的區(qū)別(typeof 1 === ‘number’, typeof ‘1’ === ‘string’),

所以我們可以使用 typeof item + item 拼成字符串作為 key 值來(lái)避免這個(gè)問(wèn)題:

var arr = [1, 2, 1, 1, '1', 3, 3, '2'];const unique = function(arr) {
    var obj = {};
    var res = [];
    arr.forEach(item => {
        if (!obj[typeof item + item]) {
            obj[typeof item + item] = true;
            res.push(item);
        }
    });
    return res;}console.log(unique(arr)); // [ 1, 2, '1', 3, '2' ]

六、ES6

隨著 ES6 的到來(lái),去重的方法又有了進(jìn)展,比如我們可以使用 Set 和 Map 數(shù)據(jù)結(jié)構(gòu)。

6.1 Set

Set:它允許你存儲(chǔ)任何類(lèi)型的唯一值,無(wú)論是原始值或者是對(duì)象引用

代碼:

var arr = [1, 2, 1, '1', '2'];const unique = function(arr) {
   return Array.from(new Set(arr));}console.log(unique(arr)); // [ 1, 2, '1', '2' ]

簡(jiǎn)化1:

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

簡(jiǎn)化2:

var unique = (a) => [...new Set(a)]
6.2 Map

Map 對(duì)象保存鍵值對(duì),并且能夠記住鍵的原始插入順序。任何值(對(duì)象或者原始值) 都可以作為一個(gè)鍵或一個(gè)值。

  • Map.prototype.has(key):返回一個(gè)布爾值,表示Map實(shí)例是否包含鍵對(duì)應(yīng)的值。

  • Map.prototype.set(key, value):設(shè)置Map對(duì)象中鍵的值。返回該Map對(duì)象。

function unique (arr) {
    const newMap = new Map()
    return arr.filter((a) => !newMap.has(a) && newMap.set(a, 1));}

寫(xiě)到這里比較常規(guī)的數(shù)組去重方法就總結(jié)的差不多了,如果需要更強(qiáng)大的去重方法,我們需要對(duì)他們進(jìn)行組合,而且因?yàn)閳?chǎng)景的不同,我們所實(shí)現(xiàn)的方法并不一定能涵蓋到

以上是“JavaScript怎么實(shí)現(xiàn)數(shù)組去重”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

名稱(chēng)欄目:JavaScript怎么實(shí)現(xiàn)數(shù)組去重
網(wǎng)站地址:http://bm7419.com/article40/pcdoho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷(xiāo)推廣網(wǎng)站收錄、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站導(dǎo)航網(wǎng)站內(nèi)鏈、網(wǎng)站設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名