TypeScript中Map和Set的實(shí)現(xiàn)示例
一、Map(映射)
Map 是 ES6 引入的一種新的數(shù)據(jù)結(jié)構(gòu),它類(lèi)似于對(duì)象,也是鍵值對(duì)的集合,但 Map 的鍵可以是任意類(lèi)型的值(對(duì)象、原始值等),而不僅僅是字符串或 Symbol。
1.基本用法
// 創(chuàng)建一個(gè)空Map const map = new Map(); // 創(chuàng)建時(shí)初始化 const initializedMap = new Map([ ['key1', 'value1'], ['key2', 'value2'] ]); // 從對(duì)象創(chuàng)建Map const obj = { a: 1, b: 2 }; const mapFromObject = new Map(Object.entries(obj));
2.常用方法和屬性
set(key, value) - 添加或更新鍵值對(duì)
map.set('name', 'Alice'); map.set(1, 'number key'); map.set({}, 'object key'); map.set(null, 'null key'); // 甚至可以使用null或undefined作為鍵
get(key) - 獲取鍵對(duì)應(yīng)的值
const name = map.get('name'); // 'Alice' const unknown = map.get('non-existent'); // undefined
has(key) - 檢查是否存在某個(gè)鍵
const hasName = map.has('name'); // true
delete(key) - 刪除某個(gè)鍵值對(duì)
const deleted = map.delete('name'); // 返回布爾值表示是否刪除成功
clear() - 清空所有鍵值對(duì)
map.clear();
size - 獲取鍵值對(duì)數(shù)量
const size = map.size;
3.遍歷方法
keys() - 返回所有鍵的迭代器
for (const key of map.keys()) { console.log(key); } // 或者轉(zhuǎn)換為數(shù)組 const keysArray = Array.from(map.keys());
values() - 返回所有值的迭代器
for (const value of map.values()) { console.log(value); }
entries() - 返回所有鍵值對(duì)的迭代器
for (const [key, value] of map.entries()) { console.log(key, value); } // 可以簡(jiǎn)寫(xiě)為 for (const [key, value] of map) { console.log(key, value); }
forEach() - 遍歷所有鍵值對(duì)
map.forEach((value, key) => { console.log(key, value); // 注意:value在前,key在后,與數(shù)組的forEach不同 });
4.TypeScript 中的類(lèi)型定義
// 明確指定鍵和值的類(lèi)型 const typedMap = new Map<string, number>(); typedMap.set('age', 25); // 正確 typedMap.set('name', 'Alice'); // 錯(cuò)誤,值應(yīng)該是number類(lèi)型 // 復(fù)雜類(lèi)型示例 interface User { id: number; name: string; } const userMap = new Map<number, User>(); userMap.set(1, { id: 1, name: 'Alice' }); // 從現(xiàn)有類(lèi)型派生Map類(lèi)型 type UserMap = Map<number, User>;
5.Map 與普通對(duì)象的區(qū)別
- Map 的鍵可以是任意類(lèi)型,而對(duì)象的鍵只能是字符串或 Symbol
- Map 的大小可以通過(guò) size 屬性直接獲取,而對(duì)象需要手動(dòng)計(jì)算
- Map 在頻繁增刪鍵值對(duì)的場(chǎng)景下性能更好
- Map 會(huì)維護(hù)鍵值對(duì)的插入順序
- Map 可以直接遍歷,而對(duì)象需要先獲取鍵數(shù)組
6.使用場(chǎng)景
- 需要鍵不是字符串/數(shù)字/Symbol的情況
- 需要頻繁增刪鍵值對(duì)的場(chǎng)景
- 需要維護(hù)插入順序的場(chǎng)景
- 需要更便捷的遍歷和大小獲取的場(chǎng)景
二、Set(集合)
Set 是 ES6 引入的另一種數(shù)據(jù)結(jié)構(gòu),它類(lèi)似于數(shù)組,但成員的值都是唯一的,沒(méi)有重復(fù)的值。
1.基本用法
// 創(chuàng)建一個(gè)空Set const set = new Set(); // 創(chuàng)建時(shí)初始化 const initializedSet = new Set([1, 2, 3, 4]); // 從類(lèi)數(shù)組對(duì)象創(chuàng)建 const arrayLike = { 0: 'a', 1: 'b', length: 2 }; const setFromArrayLike = new Set(Array.from(arrayLike)); // 字符串會(huì)被拆分為字符 const charSet = new Set('hello'); // Set {'h', 'e', 'l', 'o'}
2.常用方法和屬性
add(value) - 添加值,返回Set本身(可以鏈?zhǔn)秸{(diào)用)
set.add(1).add(2).add(3); set.add(NaN).add(NaN); // Set中NaN等于自身,只會(huì)保留一個(gè)
has(value) - 檢查是否存在某個(gè)值
const hasTwo = set.has(2); // true set.has(NaN); // 可以正確檢測(cè)NaN
delete(value) - 刪除某個(gè)值
set.delete(2);
clear() - 清空所有值
set.clear();
size - 獲取值的數(shù)量
const size = set.size;
3.遍歷方法
values() - 返回所有值的迭代器
for (const value of set.values()) { console.log(value); }
keys() - 與values()相同,為了與Map兼容
for (const key of set.keys()) { console.log(key); }
entries() - 返回[value, value]形式的迭代器,為了與Map兼容
for (const [key, value] of set.entries()) { console.log(key, value); // 兩者相同 }
forEach() - 遍歷所有值
set.forEach((value) => { console.log(value); // 注意:參數(shù)設(shè)計(jì)為與Map的forEach一致 });
4.TypeScript 中的類(lèi)型定義
// 明確指定值的類(lèi)型 const typedSet = new Set<number>(); typedSet.add(1); // 正確 typedSet.add('1'); // 錯(cuò)誤,值應(yīng)該是number類(lèi)型 // 復(fù)雜類(lèi)型示例 interface Product { id: number; name: string; } const productSet = new Set<Product>(); productSet.add({ id: 1, name: 'Laptop' }); // 從現(xiàn)有類(lèi)型派生Set類(lèi)型 type ProductSet = Set<Product>;
5.Set 與數(shù)組的區(qū)別
特性 | Set | 數(shù)組 |
---|---|---|
唯一性 | 值唯一 | 允許重復(fù)值 |
查找效率 | has方法O(1) | includes/indexOf O(n) |
添加元素 | add方法 | push/unshift等方法 |
刪除元素 | delete方法 | splice/filter等方法 |
順序 | 插入順序 | 可排序 |
索引訪問(wèn) | 不支持 | 支持下標(biāo)訪問(wèn) |
大小獲取 | size屬性 | length屬性 |
內(nèi)存占用 | 通常比數(shù)組多 | 通常更節(jié)省內(nèi)存 |
6.使用場(chǎng)景
- 需要存儲(chǔ)唯一值的場(chǎng)景
- 需要快速檢查某個(gè)值是否存在的場(chǎng)景
- 需要去重的場(chǎng)景
- 數(shù)學(xué)集合運(yùn)算(并集、交集、差集)
7.集合運(yùn)算示例
// 并集 const union = new Set([...setA, ...setB]); // 交集 const intersection = new Set([...setA].filter(x => setB.has(x))); // 差集 (A - B) const difference = new Set([...setA].filter(x => !setB.has(x)));
三、Map 和 Set 的性能特點(diǎn)
- 查找速度:Map 和 Set 的查找操作(has/get)平均時(shí)間復(fù)雜度為 O(1),比數(shù)組的 O(n) 快
- 插入速度:Map 和 Set 的插入操作平均時(shí)間復(fù)雜度為 O(1)
- 刪除速度:Map 和 Set 的刪除操作平均時(shí)間復(fù)雜度為 O(1)
- 內(nèi)存占用:Map 和 Set 通常比對(duì)象和數(shù)組占用更多內(nèi)存
- 迭代性能:Map和Set的迭代速度與數(shù)組相當(dāng),對(duì)象迭代需要Object.keys等額外步驟
四、應(yīng)用建議
- 類(lèi)型安全:
// 總是明確指定泛型類(lèi)型 const userMap = new Map<number, User>();
合理選擇數(shù)據(jù)結(jié)構(gòu):
- 需要鍵值對(duì) → Map
- 需要唯一值 → Set
- 需要索引訪問(wèn) → 數(shù)組
- 需要簡(jiǎn)單鍵值且不頻繁修改 → 對(duì)象
內(nèi)存管理:
- 對(duì)于臨時(shí)對(duì)象作為鍵/值,考慮WeakMap/WeakSet
- 大型Map/Set不再需要時(shí)手動(dòng)clear()
性能優(yōu)化:
- 避免在熱代碼路徑中頻繁創(chuàng)建新的Map/Set
- 對(duì)于大型數(shù)據(jù)集,考慮預(yù)分配大小
不可變數(shù)據(jù):
// 需要不可變Map/Set時(shí) function addToImmutableSet<T>(set: Set<T>, value: T): Set<T> { return new Set([...set, value]); }
與數(shù)組轉(zhuǎn)換:
// Map轉(zhuǎn)數(shù)組 const mapEntries = [...map.entries()]; // Set轉(zhuǎn)數(shù)組 const setValues = [...set];
自定義相等性:
// 對(duì)于對(duì)象值,需要自定義相等邏輯 const objectSet = new Set<{id: number}>(); const obj1 = {id: 1}; const obj2 = {id: 1}; objectSet.add(obj1); objectSet.has(obj2); // false,因?yàn)閷?duì)象引用不同
五、總結(jié)
特性 | Map | Set |
---|---|---|
存儲(chǔ)內(nèi)容 | 鍵值對(duì) | 唯一值 |
鍵/值類(lèi)型 | 任意類(lèi)型 | 任意類(lèi)型 |
主要方法 | set, get, has, delete | add, has, delete |
遍歷方式 | keys, values, entries | values, keys, entries |
典型用途 | 需要非字符串鍵的鍵值對(duì)存儲(chǔ) | 值唯一性檢查、集合運(yùn)算 |
是否有序 | 插入順序 | 插入順序 |
1.何時(shí)選擇Map/Set:
- 需要非字符串鍵 → Map
- 需要嚴(yán)格維護(hù)插入順序 → Map/Set
- 需要頻繁增刪元素 → Map/Set
- 需要高效存在性檢查 → Set
- 需要集合運(yùn)算 → Set
2.何時(shí)選擇對(duì)象/數(shù)組:
- 需要索引訪問(wèn) → 數(shù)組
- 簡(jiǎn)單配置對(duì)象 → 對(duì)象
- 需要方法操作(如map/filter)→ 數(shù)組
- 小型靜態(tài)數(shù)據(jù)集 → 對(duì)象/數(shù)組
在 TypeScript 中使用 Map 和 Set 時(shí),建議總是明確指定泛型類(lèi)型參數(shù),以獲得更好的類(lèi)型檢查和代碼提示。這兩種數(shù)據(jù)結(jié)構(gòu)在處理特定問(wèn)題時(shí)比傳統(tǒng)的對(duì)象和數(shù)組更高效、更直觀。
到此這篇關(guān)于TypeScript中Map和Set的實(shí)現(xiàn)示例 的文章就介紹到這了,更多相關(guān)TypeScript Map和Set內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)平滑無(wú)縫滾動(dòng)
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)平滑無(wú)縫滾動(dòng)的具體代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05個(gè)人總結(jié)的一些JavaScript技巧、實(shí)用函數(shù)、簡(jiǎn)潔方法、編程細(xì)節(jié)
這篇文章主要介紹了個(gè)人總結(jié)的一些JavaScript技巧、實(shí)用函數(shù)、簡(jiǎn)潔方法、編程細(xì)節(jié),本文講解了變量轉(zhuǎn)換、取整同時(shí)轉(zhuǎn)換成數(shù)值型、日期轉(zhuǎn)數(shù)值、類(lèi)數(shù)組對(duì)象轉(zhuǎn)數(shù)組、進(jìn)制之間的轉(zhuǎn)換等方法技巧,需要的朋友可以參考下2015-06-06JavaScript Event學(xué)習(xí)第六章 事件的訪問(wèn)
在這一章我會(huì)講解如何去訪問(wèn)一個(gè)事件對(duì)象。2010-02-02js form 驗(yàn)證函數(shù) 當(dāng)前比較流行的錯(cuò)誤提示
js數(shù)據(jù)驗(yàn)證、js email驗(yàn)證、js url驗(yàn)證、js長(zhǎng)度驗(yàn)證、js數(shù)字驗(yàn)證等2009-06-06Nuxt.js中PC與移動(dòng)端間自動(dòng)識(shí)別跳轉(zhuǎn)
本文主要介紹了Nuxt.js中PC與移動(dòng)端間自動(dòng)識(shí)別跳轉(zhuǎn),文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03基于javascript實(shí)現(xiàn)數(shù)字英文驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)數(shù)字英文驗(yàn)證碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01微信小程序網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求的實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了微信小程序網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求的實(shí)現(xiàn)講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08原生JS版和jquery版實(shí)現(xiàn)checkbox的全選/全不選/點(diǎn)選/行內(nèi)點(diǎn)選(Mr.Think)
腳本之家小編之前整理不少checkbox全選全不選這方便的文章,但看了這篇以后發(fā)現(xiàn)實(shí)現(xiàn)方法更好2016-10-10