JavaScript?數(shù)據(jù)結(jié)構(gòu)之字典方法
前言:
經(jīng)過上一篇JavaScript 數(shù)據(jù)結(jié)構(gòu)之集合創(chuàng)建(2)的學(xué)習(xí),數(shù)據(jù)結(jié)構(gòu)的集合部分已經(jīng)完結(jié)了。那么下面我們又要認(rèn)識(shí)一個(gè)新的數(shù)據(jù)結(jié)構(gòu),它的名字相信你絕不陌生,它就是字典。
這個(gè)字典可不是查漢字時(shí)用的那個(gè)字典。字典在數(shù)據(jù)結(jié)構(gòu)中也是用來存儲(chǔ)唯一的不重復(fù)的值,這一點(diǎn)倒和集合類似。不過兩者的存儲(chǔ)形式不同。
集合更關(guān)注元素本身,以元素本身的值作為唯一標(biāo)識(shí)。而字典的存儲(chǔ)形式是 鍵值對(duì)
,這個(gè)我們太熟了。以 key
為標(biāo)識(shí),value
為對(duì)應(yīng)的值,這不就是我們的 JSON 嘛。
下面我們從最基礎(chǔ)開始,學(xué)習(xí)字典。
一、什么是字典
上面說了,集合中是通過元素的值來決定元素的唯一性。然而在字典中,存儲(chǔ)的方式是鍵值對(duì),也就是 key->value
的形式,字典只要求 key 必須唯一,value 則沒有限制。
這里 key 的作用是唯一標(biāo)識(shí),用來查詢對(duì)應(yīng)的 value 值。也就是說可以通過唯一的 key 映射到對(duì)應(yīng)的 value。所以字典也稱作映射,符號(hào)表或關(guān)聯(lián)數(shù)組。
在計(jì)算機(jī)世界中,字典經(jīng)常用來標(biāo)識(shí)對(duì)象的引用地址。比如在 JavaScript 當(dāng)中的引用類型
數(shù)據(jù),變量名會(huì)指向數(shù)據(jù)的引用,這是一對(duì)映射關(guān)系。變量名不能重復(fù),但是不同的變量名可以指向同一塊引用。
與 Set 類似,JavaScript ES6 中同樣包含了一個(gè) Map
類,既我們所說的字典。
二、創(chuàng)建字典類
下面我們參照 ES6 Map 類的實(shí)現(xiàn),自己動(dòng)手實(shí)現(xiàn)一個(gè) Dictionary
類。
class Dictionary { constructor() { this.table = {} } }
與前面的其他數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)類似,我們?cè)谝粋€(gè)對(duì)象 table
中存儲(chǔ)所有字典的元素。我們的保存形式為:table[key] = {key, value}
。
在字典中,通常是用字符串作為鍵名(key),數(shù)據(jù)值可以是任意類型。但是 JavaScript 并不是強(qiáng)類型的語言,無法保證傳入的鍵名一定是字符串。所以我們需要將鍵名做一次字符串的轉(zhuǎn)化。
寫一個(gè)默認(rèn)的轉(zhuǎn)換字符串函數(shù):
function keyToString(item) { if(typeof item === null) { return 'NULL' } if(typeof item === undefined) { return 'UNDEFINED' } if(item instanceof String) { return `${item}` } return item.toString() }
除此之外,我們還有必要將鍵值對(duì)的數(shù)據(jù)格式封裝成一個(gè)單獨(dú)的類。因?yàn)槲覀兊?key 是不固定的,然而在后面的方法中要頻繁使用 key,此時(shí)你不知道鍵名具體是什么。所以要封裝一個(gè) ValuePair
類,定義如下:
class ValuePair { constructor(key, value) { this.key = key; this.value = value; } }
接下來在類中聲明一些必要的方法如下:
set
:向字典中添加新元素remove
:以鍵名為參數(shù),移除字典中對(duì)應(yīng)的鍵值hasKey
:檢測(cè)某個(gè)鍵名是否存在于字典中,存在則返回 trueget
:用鍵名查找對(duì)應(yīng)的鍵值并返回clear
:清空字典size
:返回字典所包含鍵的數(shù)量isEmpty
:在 size 等于零時(shí)返回 truekeys
:返回字典中所有鍵名組成的數(shù)組values
:返回字典中所有鍵值組成的數(shù)組keyValues
:返回所有鍵值對(duì)forEach
:迭代所有的鍵值對(duì)
1.hasKey 方法
該方法的作用是檢測(cè)一個(gè)鍵是否在字典中。因?yàn)檫@個(gè)方法會(huì)在添加和刪除元素時(shí)使用,所以先實(shí)現(xiàn):
hasKey(key) { return this.table[keyToString(key)] != null }
首先對(duì)傳入的鍵進(jìn)行字符串轉(zhuǎn)換,然后判斷鍵值是不是 null
或者 undefined
。
2.set 方法
set 方法用來在字典中添加鍵值對(duì):
set(key, value) { if(key != null && value != null) { let table_key = keyToString(key) this.table[table_key] = new ValuePair(key, value) return true } return false }
3.remove 方法
remove 方法用來在字典中刪除一個(gè)鍵值對(duì):
remove(key) { if(this.hasKey(key)) { delete this.table[keyToString(key)] return true } return false }
4.get 方法
get 方法用來獲取鍵名對(duì)應(yīng)的鍵值:
get(key) { if(this.hasKey(key)) { let table_key = keyToString(key) return this.table[table_key].value } return undefined }
5.keys, values, keyValues 方法
這三個(gè)是比較簡(jiǎn)單的輔助函數(shù),一起介紹:
keyValues() { return Object.values(this.table) } keys() { return this.keyValues().map(valuePair=> valuePair.key) } values() { return this.keyValues().map(valuePair=> valuePair.value) }
首先 keyValues
方法會(huì)以數(shù)組的形式返回字典的所有鍵值,返回結(jié)果是一個(gè) ValuePair 實(shí)例的數(shù)組。然后在這個(gè)函數(shù)的基礎(chǔ)上,再分別獲取對(duì)應(yīng)的 key 數(shù)組和 value 數(shù)組。
6.forEach 方法
forEach 方法與數(shù)組的 forEach 方法功能一致,就是迭代所有元素,我們看一下迭代字典的所有值怎么實(shí)現(xiàn):
forEach(callFn) { let valuePairs = this.keyValues() for(let i = 0; i < valuePairs.length; i++) { let result = callFn(valuePairs[i].key, valuePairs[i].value) if(result === false) break; } }
首先傳一個(gè)回調(diào)函數(shù)作為參數(shù),然后遍歷字典的長(zhǎng)度,并在循環(huán)里調(diào)用這個(gè)回調(diào)函數(shù)。這里我們的一個(gè)設(shè)計(jì)是,如果在回調(diào)函數(shù)內(nèi)返回 false
,則會(huì)中斷循環(huán)。
7.clear, size, isEmpty 方法
這個(gè)三個(gè)方法也比較基礎(chǔ):
size() { return Object.keys(this.table).length; } isEmpty() { return this.size() === 0 } clear() { this.table = {} }
三、使用字典
前面我們寫了不少方法實(shí)現(xiàn)了一個(gè)字典類,現(xiàn)在來使用一下:
var dict = new Dictionary(); dict.set("name", "賽羅"); dict.set("color", "紅藍(lán)"); dict.set("skill", "頭標(biāo)");
添加了三個(gè)鍵值對(duì),我們看一下基本方法的返回結(jié)果:
console.log(dict.keys()); // ['name', 'color', 'skill'] console.log(dict.values()); // ['賽羅', '紅藍(lán)', '頭標(biāo)'] console.log(dict.size()); // 3 console.log(dict.hasKey("color")); // true console.log(dict.get("color")); // 紅藍(lán) console.log(dict.hasKey("like")); // false console.log(dict.get("like")); // undefined
看結(jié)果都沒問題,再來一波遍歷:
dict.forEach((key, value) => { console.log(key, value); if (key === "color") return false; }); // 打印結(jié)果: // name 賽羅 // color 紅藍(lán)
可見循環(huán)遍歷是沒有問題的,而且當(dāng)函數(shù)執(zhí)行返回 false 時(shí),則會(huì)終止遍歷,因此第三個(gè)鍵值對(duì)沒有打印出來,結(jié)果達(dá)標(biāo)。
最后再看一下刪除:
// 刪除鍵值對(duì) console.log(dict.remove("color")); // true console.log(dict.remove("like")); // false console.log(dict.remove("skill")); // true console.log(dict.keyValues()); // [ValuePair] console.log(dict.hasKey("color")); false console.log(dict.size()); 1 // 清空字典 dict.clear(); console.log(dict.keyValues()); // [] console.log(dict.isEmpty()); // true
也沒問題,結(jié)果完美!
四、總結(jié)
本篇從頭到尾介紹了字典的相關(guān)知識(shí),你學(xué)會(huì)了嗎?雖然 ES6 提供了原生支持,但是對(duì)于我們學(xué)習(xí)者來說,手動(dòng)實(shí)現(xiàn)一次更有助于了解原理。
到此這篇關(guān)于JavaScript 數(shù)據(jù)結(jié)構(gòu)之字典方法的文章就介紹到這了,更多相關(guān)JavaScript 字典內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS實(shí)現(xiàn)網(wǎng)頁上隨滾動(dòng)條滾動(dòng)的層效果代碼
這篇文章主要介紹了JS實(shí)現(xiàn)網(wǎng)頁上隨滾動(dòng)條滾動(dòng)的層效果代碼,涉及JavaScript頁面元素屬性的獲取、運(yùn)算及設(shè)置等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11javascript命名約定(變量?函數(shù)?類?組件)
這篇小文章主要是通過一些例子來介紹一些Javascript中一些關(guān)于命名變量,函數(shù),類或者是組件的通用約定,雖然這些規(guī)則并不是強(qiáng)制性的,但是呢,他們卻被一些JS社區(qū)所廣泛采用,所以,了解他們還是很有必要的2023-03-03深入淺出webpack教程系列_安裝與基本打包用法和命令參數(shù)詳解
下面小編就為大家?guī)硪黄钊霚\出webpack教程系列_安裝與基本打包用法和命令參數(shù)詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就想給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09JavaScript實(shí)現(xiàn)圖片懶加載的三種方案詳解
圖片懶加載,當(dāng)圖片出現(xiàn)在可視區(qū)域再進(jìn)行加載,提升用戶的體驗(yàn),這篇文章主要為大家整理了三個(gè)常用的圖片懶加載實(shí)現(xiàn)方法,希望對(duì)大家有所幫助2023-12-12js定時(shí)器+簡(jiǎn)單的動(dòng)畫效果實(shí)例
下面小編就為大家?guī)硪黄猨s定時(shí)器+簡(jiǎn)單的動(dòng)畫效果實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11JS實(shí)現(xiàn)的自定義顯示加載等待圖片插件(loading.gif)
這篇文章主要介紹了JS實(shí)現(xiàn)的自定義顯示加載等待圖片插件,涉及javascript針對(duì)圖片的動(dòng)態(tài)加載實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06JavaScript中數(shù)組對(duì)象的那些自帶方法介紹
數(shù)組對(duì)象自帶方法想必大家都有所耳聞,今天主要為大家介紹下JavaScript中數(shù)組對(duì)象的那些自帶方法,感興趣的你可以參考下哈,希望可以幫助你學(xué)習(xí)javascript2013-03-03