日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用

發(fā)布時(shí)間:2023/12/4 HTML 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一文了解集合和字典在前端中的應(yīng)用

  • 一、📝集合
    • 1、集合是什么?
    • 2、前端與集合:使用ES6中的Set
    • 3、用Set模擬并集、交集和差集
      • (1)模擬并集運(yùn)算
      • (2)模擬交集運(yùn)算
      • (3)模擬差集運(yùn)算
    • 4、使用擴(kuò)展運(yùn)算符來模擬并集、交集和差集
      • (1)用擴(kuò)展運(yùn)算符實(shí)現(xiàn)并集
      • (2)用擴(kuò)展運(yùn)算符實(shí)現(xiàn)交集
      • (3)用擴(kuò)展運(yùn)算符實(shí)現(xiàn)差集
    • 5、leetcode案例題分析
      • (1)leetcode349兩個(gè)數(shù)組的交集
  • 二、📂字典
    • 1、字典是什么?
    • 2、前端與集合:使用ES6中的Map
    • 3、使用Map類的API
    • 4、leetcode案例題分析
      • (1)leetcode349兩個(gè)數(shù)組的交集
      • (2)leetcode20有效地括號(hào)
      • (3)leetcode1兩數(shù)之和
      • (4)leetcode3無重復(fù)字符的最長子串
      • (5)leetcode76最小覆蓋子串
  • 三、📆結(jié)束語

在前端日新月異的大背景下, ES6 也基本已經(jīng)覆蓋性地全民普及。而數(shù)據(jù)結(jié)構(gòu)集合和字典,也被運(yùn)用于 ES6 的語法當(dāng)中。 ES6 通過使用 Set 和 Map 這兩個(gè)函數(shù),來實(shí)現(xiàn)集合和字典的思想。而集合和字典,又是怎么被靈活應(yīng)用的呢?

下面的這篇文章中,將帶領(lǐng)大家來一起了解集合和字典在前端中應(yīng)用,并使用 Map 和 Set 來實(shí)現(xiàn)前端的一些常見場(chǎng)景。一起來學(xué)習(xí)吧~🙋?♀?

一、📝集合

1、集合是什么?

  • 集合是一種無序且唯一的數(shù)據(jù)結(jié)構(gòu);
  • ES6 中有集合,名為 Set ;
  • 集合的常用操作: 去重、判斷某元素是否在集合中、求交集……

2、前端與集合:使用ES6中的Set

ES6 中的 Set 可以做什么呢?

  • 使用 Set 對(duì)象: new 、 add 、 delete 、 has 、 size
  • 迭代 Set :多種迭代方法、 Set 與 Array 互轉(zhuǎn)、求并集/交集/差集

3、用Set模擬并集、交集和差集

(1)模擬并集運(yùn)算

我們可以創(chuàng)建一個(gè)函數(shù),來返回包含 setA 和 setB 中所有元素的新集合。迭代這兩個(gè)集合,并把所有元素都添加到并集的集合中。如下代碼所示:

//模擬并集運(yùn)算 const union = (setAe, setB) => {const unionab = new Set()setA.forEach(value => unionab.add(value))setB.forEach(value => unionab.add(value))return [...unionab] }console.log(union([1, 2, 5, 8, 9], [4, 5, 8, 9, 10])) //[1, 2, 5, 8,9, 4, 10]

(2)模擬交集運(yùn)算

模擬交集運(yùn)算需要?jiǎng)?chuàng)建一個(gè)輔助函數(shù),來生成包含 setA 和 setB 兩個(gè)集合中共同擁有元素的新集合。具體代碼如下:

// 模擬交集運(yùn)算 const intersection = (setA, setB) => {const intersectionSet = new Set()const arrSetB = new Set(setB)setA.forEach(value => {if (arrSetB.has(value)) {intersectionSet.add(value)}})return [...intersectionSet] }console.log(intersection([1, 2, 5, 8, 9], [4, 5, 8, 9, 10])) //[5,8,9]

(3)模擬差集運(yùn)算

差集運(yùn)算是創(chuàng)建集合 setA 有,而集合 setB 沒有的元素。簡單來說,就是 setA 減去和 setB 相交的部分,剩余的部分即是差集的部分。

// 模擬差集運(yùn)算 const difference = (setA, setB) => {const differenceSet = new Set()const arrSetB = new Set(setB)setA.forEach(value => {if (!arrSetB.has(value)) {differenceSet.add(value)}})return [...differenceSet] }console.log(difference([1, 2, 5, 8, 9], [4, 5, 8, 9, 10])) //[1, 2]

4、使用擴(kuò)展運(yùn)算符來模擬并集、交集和差集

上面我們實(shí)現(xiàn)了用Set來模擬并集、交集和差集,但這似乎有一點(diǎn)點(diǎn)冗余,如果遇到數(shù)據(jù)量大的時(shí)候還每一次都要執(zhí)行這么多行代碼,似乎這樣子聽起來就那么友好了。

因此,我們引入了一種新的方法來解決,ES6的擴(kuò)展運(yùn)算符。

如果使用擴(kuò)展運(yùn)算符來進(jìn)行運(yùn)算的話,整個(gè)過程只需要三個(gè)步驟:

  • 將集合轉(zhuǎn)化為數(shù)組;
  • 執(zhí)行需要的運(yùn)算;
  • 將結(jié)果轉(zhuǎn)化回集合。

接下來我們就用擴(kuò)展運(yùn)算符,來一一實(shí)現(xiàn)并集、交集和差集

(1)用擴(kuò)展運(yùn)算符實(shí)現(xiàn)并集

來看下面一段代碼:

// 模擬并集運(yùn)算 const union = (setA, setB) => {return new Set([...setA, ...setB]); } console.log(union([1, 2, 5, 8, 9], [4, 5, 8, 9, 10])) //[1, 2, 5, 8,9, 4, 10]

通過以上代碼我們可以看到,使用擴(kuò)展運(yùn)算符,只需要短短一行代碼,即可實(shí)現(xiàn)具體的并集運(yùn)算,這樣看起來簡潔了許多。

接下來我們繼續(xù)用這種方法,來實(shí)現(xiàn)交集差集。

(2)用擴(kuò)展運(yùn)算符實(shí)現(xiàn)交集

// 模擬交集運(yùn)算 const intersection = (setA, setB) => {const arrB = new Set(setB);return [...new Set([...setA].filter(x => arrB.has(x)))] } console.log(intersection([1, 2, 5, 8, 9], [4, 5, 8, 9, 10])) //[5, 8, 9]

與并集一樣的效果,運(yùn)用擴(kuò)展運(yùn)算符,很簡潔的就實(shí)現(xiàn)了交集的功能。

(3)用擴(kuò)展運(yùn)算符實(shí)現(xiàn)差集

// 模擬差集運(yùn)算 const difference = (setA, setB) => {const arrB = new Set(setB)return [...new Set([...setA].filter(x => !arrB.has(x)))] } console.log(difference([1, 2, 5, 8, 9], [4, 5, 8, 9, 10])) //[1, 2]

同樣地,使用擴(kuò)展運(yùn)算符的方法,但與交集相反的是,交集是篩選出集合setB擁有的元素,而差集是篩選出集合setB沒有的元素,從而最終達(dá)到具體效果。

5、leetcode案例題分析

(1)leetcode349兩個(gè)數(shù)組的交集

1)題意

這里附上原題鏈接

給定兩個(gè)數(shù)組,編寫一個(gè)函數(shù)來計(jì)算它們的交集。

輸入輸出示例:

  • 輸入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
  • 輸出: [9,4]
  • 解釋:
    • nums1 和 nums2 兩個(gè)數(shù)組的相交部分為 [9, 4] 。

2)解題思路

  • 求交集且無序唯一。
  • 使用集合。

3)解題步驟

  • 用集合對(duì) nums1 去重。
  • 遍歷 nums1 ,篩選出 nums2 中也包含的值。

4)代碼實(shí)現(xiàn)

/*** @param {Array} nums1 數(shù)組1* @param {Array} nums2 數(shù)組2* @returns */ let intersection = function(nums1, nums2){// 先進(jìn)行數(shù)組去重const arr1 = new Set(nums1);const arr2 = new Set(nums2);// 過濾掉arr1在arr2中已經(jīng)有的元素,過濾結(jié)果即為交集// has可改為includesconst arr3 = [...arr1].filter(item => arr2.has(item));return arr3; } console.log(intersection([1,2,3,4],[4,6,8]))

二、📂字典

1、字典是什么?

  • 字典與集合相似,字典也是一種存儲(chǔ)唯一值的數(shù)據(jù)結(jié)構(gòu),但它是以鍵值對(duì)的形式來存儲(chǔ)。
  • 注意:字典一定是以鍵值對(duì)的形式存儲(chǔ)!!

2、前端與集合:使用ES6中的Map

ES6中的Map可以做什么呢?

  • 使用 Map 對(duì)象: new 、 set 、 delete 、 clear ;
  • 字典的常用操作,鍵值對(duì)的增刪改查

3、使用Map類的API

下面展示一段代碼,來展示 map 的相關(guān) API 。

const map = new Map()//增 map.set('monday', '星期一') map.set('Tuesday', '星期二') map.set('Wednesday', '星期三')console.log(map.has('monday')) //true console.log(map.size) //3 console.log(map.keys()) //輸出{'monday', 'Tuesday', 'Wednesday'} console.log(map.values()) //輸出{'星期一', '星期二', '星期三'} console.log(map.get('monday')) //星期一//刪 map.delete('monday')//清空 map.clear()//改 map.set('monday', '星期四')

4、leetcode案例題分析

(1)leetcode349兩個(gè)數(shù)組的交集

1)題意

這里附上原題鏈接

給定兩個(gè)數(shù)組,編寫一個(gè)函數(shù)來計(jì)算它們的交集。

輸入輸出示例:

  • 輸入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
  • 輸出: [9,4]
  • 解釋:
    • nums1 和 nums2 兩個(gè)數(shù)組的相交部分為 [9, 4] 。

2)解題思路

  • 求 nums1 和 nums2 都有的值。
  • 字典建立一個(gè)映射關(guān)系,記錄 nums1 里有的值。
  • 遍歷 nums2 ,找出 nums1 里也有的值。

3)解題步驟

  • 新建一個(gè)字典,遍歷 nums1 ,填充字典
  • 遍歷 nums2 ,遇到字典里的值就選出,并從字典中刪除。

4)代碼實(shí)現(xiàn)

/*** @param {Array} nums1 數(shù)組1* @param {Array} nums2 數(shù)組2* @returns */ let intersection = function(nums1, nums2){// 先建立一個(gè)字典const map = new Map();// 遍歷nums1的每一個(gè),并放入數(shù)組中nums1.forEach(n => {map.set(n, true);});const res = [];// 遍歷nums2中的每一個(gè)nums2.forEach(n => {// 與nums1中的對(duì)比,如果一樣則push進(jìn)resif(map.get(n)){res.push(n);map.delete(n);}});return res; }console.log(intersection([1, 2, 2, 1], [2, 2]))

(2)leetcode20有效地括號(hào)

1)題意

這里附上原題鏈接

給定一個(gè)只包括 '(',')','{','}','[',']' 的字符串 s ,判斷字符串是否有效。

輸入輸出示例:

  • 輸入: s = “()[]{}”
  • 輸出: true
  • 解釋:
    • 左括號(hào)和右括號(hào)對(duì)應(yīng)開閉。

2)解題步驟

  • 判斷字符串的個(gè)數(shù)是否為偶數(shù),不是則直接返回。
  • 建立一個(gè)字典,分別將三個(gè)括號(hào)映射進(jìn)入。
  • 遍歷字符串
  • 遍歷 nums1 ,篩選出 nums2 中也包含的值。

3)代碼實(shí)現(xiàn)

/*** * @param {String} s 括號(hào)字符串* @returns boolean*/let isValid = function(s){if(s.length % 2 === 1){return false;}const stack = [];const map = new Map();map.set('(', ')');map.set('{', '}');map.set('[', ']');for(let i = 0; i < s.length; i++){const c = s[i];if(map.has(c)){stack.push(c);}else{// 獲取棧中最后一個(gè)括號(hào)的值const t = stack[stack.length - 1];if(map.get(t) === c){stack.pop();}else{return false;}}}return stack.length === 0; }console.log(isValid('[]')) //true console.log(isValid('(]')) //false console.log(isValid('([)]')) //false

(3)leetcode1兩數(shù)之和

1)題意

這里附上原題鏈接

給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)整數(shù)目標(biāo)值 target,請(qǐng)你在該數(shù)組中找出 和為目標(biāo)值 target 的那兩個(gè)整數(shù),并返回它們的數(shù)組下標(biāo)。

你可以假設(shè)每種輸入只會(huì)對(duì)應(yīng)一個(gè)答案。但是,數(shù)組中同一個(gè)元素在答案里不能重復(fù)出現(xiàn)。

你可以按任意順序返回答案。

輸入輸出示例:

  • 輸入: nums = [2,7,11,15], target = 9
  • 輸出: [0,1]
  • 解釋:
    • 因?yàn)?nums[0] + nums[1] == 9 ,返回 [0, 1] 。

2)解題思路

  • 把 nums 想象成相親者;
  • 把 target 想象成匹配條件;
  • 用字典建立一個(gè)婚姻介紹所,存儲(chǔ)相親者的數(shù)字和下標(biāo)。

3)解題步驟

  • 新建一個(gè)字典作為婚姻介紹所;
  • nums 的值,逐個(gè)來介紹所找的對(duì)象,沒有合適的就先登記,有合適的就牽手成功;
  • 鍵值對(duì),鍵 key 代表此對(duì)象的值,值 value 代表對(duì)象的聯(lián)系方式,即下標(biāo)。

4)代碼實(shí)現(xiàn)

/*** * @param {Array} nums 數(shù)組* @param {Number} target 目標(biāo)和 * @returns []*/ let twoSum = function(nums, target){const map = new Map();for(i = 0; i < nums.length; i++){// 來找對(duì)象的人的值const n = nums[i];// 想找的目標(biāo)對(duì)象的值const n2 = target - n;// 找到對(duì)象時(shí)if(map.has(n2)){return [map.get(n2), i];}// 找不到對(duì)象時(shí),放進(jìn)字典里等待對(duì)象的到來else{map.set(n, i);}}return '沒有目標(biāo)匹配'; }console.log(twoSum([1, 2, 3, 4], 6)) //[1, 3]

(4)leetcode3無重復(fù)字符的最長子串

1)題意

這里附上原題鏈接

給定一個(gè)字符串,請(qǐng)你找出其中不含有重復(fù)字符的 最長子串 的長度。

輸入輸出示例:

  • 輸入: s = “abcabcbb”

  • 輸出: 3

  • 解釋:

    • 因?yàn)闊o重復(fù)字符的最長子串是 "abc" ,所以其長度為 3 。
  • 2)解題思路

    • 先找出所有的不包含重復(fù)字符的子串。
    • 找出長度最大的那個(gè)子串,返回其長度即可。

    3)解題步驟

    • 用雙指針維護(hù)一個(gè)滑動(dòng)窗口,用來剪切子串
    • 不斷移動(dòng)右指針,遇到重復(fù)字符,就把左指針移動(dòng)到重復(fù)字符的下一位。
    • 過程中,記錄所有窗口的長度,并返回最大值。

4)代碼實(shí)現(xiàn)

/*** @param {string} s* @return {number}*/ let lengthOfLongestSubstring = function(s){let l = 0;let res = 0;const map = new Map();for(let r = 0; r < s.length; r++){// map.get(r) >= l 確保下標(biāo)在左指針右邊if(map.has(s[r]) && map.get(s[r]) >= l){l = map.get(s[r]) + 1;}res = Math.max(res, r - l + 1);map.set(s[r], r);}return res; }console.log(lengthOfLongestSubstring('ssdfsf')) // 3

(5)leetcode76最小覆蓋子串

1)題意

這里附上原題鏈接

給你一個(gè)字符串 s 、一個(gè)字符串 t 。返回 s 中涵蓋 t 所有字符的最小子串。如果 s 中不存在涵蓋 t 所有字符的子串,則返回空字符串 "" 。

**注意:**如果 s 中存在這樣的子串,我們保證它是唯一的答案。

輸入輸出示例:

  • 輸入: s = “ADOBECODEBANC”, t = “ABC”
  • 輸出: “BANC”
  • 解釋:
    • BANC 覆蓋 ABC 三個(gè)字母,并且是最小子串。

2)解題思路

  • 先找出所有包含 T 的子串。
  • 找出長度最小的那個(gè)子串,返回即可。

3)解題步驟

  • 雙指針維護(hù)一個(gè)滑動(dòng)窗口。
  • 移動(dòng)右指針,找到包含 T 的子串,移動(dòng)左指針,盡量減少包含 T 的子串的長度。

4)代碼實(shí)現(xiàn)

/*** @param {string} s* @param {string} t* @return {string}*/ let minWindow = function(s, t){// 用雙指針維護(hù)一個(gè)滑動(dòng)窗口// 指針初始位置都在第一個(gè)位置,即下標(biāo)索引為0let l = 0;let r = 0;// 建立一個(gè)字典,用來表示子串需要的字符以及它的個(gè)數(shù)const need = new Map();for(let c of t){// 遍歷子串的字符,存放到字典里need.set(c, need.has(c) ? need.get(c) + 1 : 1);}// 需要的類型數(shù)量let needType = need.size;let res = '';// 移動(dòng)右指針while(r < s.length){// 在右指針不斷移動(dòng)的過程中,我們不斷獲取當(dāng)前的字符const c = s[r];// 判斷當(dāng)前字符是否在我們的需求列表里面if(need.has(c)){need.set(c, need.get(c) - 1);if (need.get(c) === 0){needType -= 1;}}while(needType === 0){// 打印滑動(dòng)窗口及表示的子串// substring方法遵循左閉右開原則// console.log(s.substring(l, r + 1));const newRes = s.substring(l, r + 1);// 找出最小的子串if(!res || newRes.length < res.length){res = newRes;}// c2代表左指針當(dāng)前的字符const c2 = s[l];// 如果左指針在需求列表里面if(need.has(c2)){// 字符的需求數(shù)量就需要增加need.set(c2, need.get(c2) + 1);// 如果字符需求數(shù)量為1,原來是0,現(xiàn)在是1,那么就重新需要此字符if (need.get(c2) === 1){needType += 1;}}l += 1;}//當(dāng)跳出while循環(huán)時(shí),意味著左指針不能再移動(dòng),要開始移動(dòng)右指針// 右指針移動(dòng)則遞增1r += 1;}return res; }console.log(minWindow('ASDFFGFGCX','AFG')) // ASDFFG

三、📆結(jié)束語

字典和集合可以算是前端面試的必考題了,同時(shí)在日常開發(fā)中的使用頻率也相對(duì)較高,因此掌握字典和集合的內(nèi)容是較為重要的。

關(guān)于字典和集合在前端中的應(yīng)用就講到這里啦!希望對(duì)大家有幫助!

  • 關(guān)注公眾號(hào) 星期一研究室 ,第一時(shí)間關(guān)注學(xué)習(xí)干貨,更多精彩專欄待你解鎖~
  • 如果這篇文章對(duì)你有用,記得 一鍵三連 再走哦~
  • 不期而遇,我們下期見!🥂🥂🥂

總結(jié)

以上是生活随笔為你收集整理的ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。