JavaScript?數(shù)據(jù)結構之字典方法
前言:
經(jīng)過上一篇JavaScript 數(shù)據(jù)結構之集合創(chuàng)建(2)的學習,數(shù)據(jù)結構的集合部分已經(jīng)完結了。那么下面我們又要認識一個新的數(shù)據(jù)結構,它的名字相信你絕不陌生,它就是字典。
這個字典可不是查漢字時用的那個字典。字典在數(shù)據(jù)結構中也是用來存儲唯一的不重復的值,這一點倒和集合類似。不過兩者的存儲形式不同。
集合更關注元素本身,以元素本身的值作為唯一標識。而字典的存儲形式是 鍵值對,這個我們太熟了。以 key 為標識,value 為對應的值,這不就是我們的 JSON 嘛。
下面我們從最基礎開始,學習字典。
一、什么是字典
上面說了,集合中是通過元素的值來決定元素的唯一性。然而在字典中,存儲的方式是鍵值對,也就是 key->value 的形式,字典只要求 key 必須唯一,value 則沒有限制。
這里 key 的作用是唯一標識,用來查詢對應的 value 值。也就是說可以通過唯一的 key 映射到對應的 value。所以字典也稱作映射,符號表或關聯(lián)數(shù)組。
在計算機世界中,字典經(jīng)常用來標識對象的引用地址。比如在 JavaScript 當中的引用類型數(shù)據(jù),變量名會指向數(shù)據(jù)的引用,這是一對映射關系。變量名不能重復,但是不同的變量名可以指向同一塊引用。
與 Set 類似,JavaScript ES6 中同樣包含了一個 Map 類,既我們所說的字典。
二、創(chuàng)建字典類
下面我們參照 ES6 Map 類的實現(xiàn),自己動手實現(xiàn)一個 Dictionary 類。
class Dictionary {
constructor() {
this.table = {}
}
}與前面的其他數(shù)據(jù)結構實現(xiàn)類似,我們在一個對象 table 中存儲所有字典的元素。我們的保存形式為:table[key] = {key, value}。
在字典中,通常是用字符串作為鍵名(key),數(shù)據(jù)值可以是任意類型。但是 JavaScript 并不是強類型的語言,無法保證傳入的鍵名一定是字符串。所以我們需要將鍵名做一次字符串的轉(zhuǎ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()
}除此之外,我們還有必要將鍵值對的數(shù)據(jù)格式封裝成一個單獨的類。因為我們的 key 是不固定的,然而在后面的方法中要頻繁使用 key,此時你不知道鍵名具體是什么。所以要封裝一個 ValuePair 類,定義如下:
class ValuePair {
constructor(key, value) {
this.key = key;
this.value = value;
}
}接下來在類中聲明一些必要的方法如下:
set:向字典中添加新元素remove:以鍵名為參數(shù),移除字典中對應的鍵值hasKey:檢測某個鍵名是否存在于字典中,存在則返回 trueget:用鍵名查找對應的鍵值并返回clear:清空字典size:返回字典所包含鍵的數(shù)量isEmpty:在 size 等于零時返回 truekeys:返回字典中所有鍵名組成的數(shù)組values:返回字典中所有鍵值組成的數(shù)組keyValues:返回所有鍵值對forEach:迭代所有的鍵值對
1.hasKey 方法
該方法的作用是檢測一個鍵是否在字典中。因為這個方法會在添加和刪除元素時使用,所以先實現(xiàn):
hasKey(key) {
return this.table[keyToString(key)] != null
}首先對傳入的鍵進行字符串轉(zhuǎn)換,然后判斷鍵值是不是 null 或者 undefined。
2.set 方法
set 方法用來在字典中添加鍵值對:
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 方法用來在字典中刪除一個鍵值對:
remove(key) {
if(this.hasKey(key)) {
delete this.table[keyToString(key)]
return true
}
return false
}4.get 方法
get 方法用來獲取鍵名對應的鍵值:
get(key) {
if(this.hasKey(key)) {
let table_key = keyToString(key)
return this.table[table_key].value
}
return undefined
}5.keys, values, keyValues 方法
這三個是比較簡單的輔助函數(shù),一起介紹:
keyValues() {
return Object.values(this.table)
}
keys() {
return this.keyValues().map(valuePair=> valuePair.key)
}
values() {
return this.keyValues().map(valuePair=> valuePair.value)
}首先 keyValues 方法會以數(shù)組的形式返回字典的所有鍵值,返回結果是一個 ValuePair 實例的數(shù)組。然后在這個函數(shù)的基礎上,再分別獲取對應的 key 數(shù)組和 value 數(shù)組。
6.forEach 方法
forEach 方法與數(shù)組的 forEach 方法功能一致,就是迭代所有元素,我們看一下迭代字典的所有值怎么實現(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;
}
}首先傳一個回調(diào)函數(shù)作為參數(shù),然后遍歷字典的長度,并在循環(huán)里調(diào)用這個回調(diào)函數(shù)。這里我們的一個設計是,如果在回調(diào)函數(shù)內(nèi)返回 false,則會中斷循環(huán)。
7.clear, size, isEmpty 方法
這個三個方法也比較基礎:
size() {
return Object.keys(this.table).length;
}
isEmpty() {
return this.size() === 0
}
clear() {
this.table = {}
}三、使用字典
前面我們寫了不少方法實現(xiàn)了一個字典類,現(xiàn)在來使用一下:
var dict = new Dictionary();
dict.set("name", "賽羅");
dict.set("color", "紅藍");
dict.set("skill", "頭標");添加了三個鍵值對,我們看一下基本方法的返回結果:
console.log(dict.keys()); // ['name', 'color', 'skill']
console.log(dict.values()); // ['賽羅', '紅藍', '頭標']
console.log(dict.size()); // 3
console.log(dict.hasKey("color")); // true
console.log(dict.get("color")); // 紅藍
console.log(dict.hasKey("like")); // false
console.log(dict.get("like")); // undefined看結果都沒問題,再來一波遍歷:
dict.forEach((key, value) => {
console.log(key, value);
if (key === "color") return false;
});
// 打印結果:
// name 賽羅
// color 紅藍可見循環(huán)遍歷是沒有問題的,而且當函數(shù)執(zhí)行返回 false 時,則會終止遍歷,因此第三個鍵值對沒有打印出來,結果達標。
最后再看一下刪除:
// 刪除鍵值對
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也沒問題,結果完美!
四、總結
本篇從頭到尾介紹了字典的相關知識,你學會了嗎?雖然 ES6 提供了原生支持,但是對于我們學習者來說,手動實現(xiàn)一次更有助于了解原理。
到此這篇關于JavaScript 數(shù)據(jù)結構之字典方法的文章就介紹到這了,更多相關JavaScript 字典內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript中輕松獲取頁面參數(shù)值的N種方法(含代碼示例)
本文旨在深入淺出地揭示如何在JavaScript中巧妙提取那些隱藏在URL背后的寶貴信息,從基礎方法到高級技巧,一網(wǎng)打盡,無論你是編程界的菜鳥還是久經(jīng)沙場的老將,這里都有值得你品鑒的“珍饈”,需要的朋友可以參考下2024-06-06
JavaScript中三個等號和兩個等號的區(qū)別(== 和 ===)淺析
javascript中比較運算符'=='與'==='可能大家用的比較多,但是大家對他的區(qū)別不是很清楚,接下來小編給大家介紹下js中三個等號和兩個等號的區(qū)別(== 和 ===),感興趣的朋友可以參考下2016-09-09
Javascript調(diào)試腳本的經(jīng)驗之談
隨著用JavaScript編程的深入,你會開始理解那些JavaScript給出的不透明錯誤信息。一旦你理解了你常犯的一般性錯誤,你就會很快知道怎樣避免它們,這樣你寫的代碼中的錯誤將越來越少。2008-10-10

