什麼是字典?
- 字典和集合很相似,集合以[值,值]的形式儲存元素,字典則以[鍵,值]的形式來儲存元素。字典也稱作對映、符號表、或關聯陣列。
建立字典類
class Dictionary {
constructor() {
this.table = {}; // 儲存字典中的元素
}
}
複製程式碼
- 如果能使用Object的例項儲存字典中的元素時,儘量使用物件而不是陣列。
建立幾個字典中方法
- toStrFn(key) 轉字串
toStrFn (key){
if (key === null) {
return 'NULL';
} else if (key === undefined) {
return 'UNDEFINED';
} else if (typeof key === 'string' || key instanceof String) {
return `${key}`;
}else if ( Object.prototype.toString.call({})==='[object Object'] ){
return JSON.stringify(obj)
}
return key.toString();
}
複製程式碼
- 在字典中,理想的情況是用字串作為鍵名,值可以是任何型別。但是由於Javascript不是強型別的語言,我們不能保證鍵一定是字串。我們需要把所有作為鍵名傳入的物件轉化為字串。
- hasKey(key) 檢查字典中是否存在某個相同的key,存在返回true,反之false
hasKey(key) { // 檢查字典中是否存在某個相同的key,存在返回true,反之false
return this.table[this.toStrFn(key)] != null;
}
複製程式碼
- set(key, value)新增新元素,如果key存在,會覆蓋
class ValuePair { // 此類用來儲存table物件上的key屬性
constructor(key, value) {
this.key = key;
this.value = value;
}
toString() {
return `[#${this.key}: ${this.value}]`;
}
}
set(key, value) {
if (key != null && value != null) {
const tableKey = this.toStrFn(key); // 獲取表示key的字串
this.table[tableKey] = new ValuePair(key, value); // 例項化ValuePair類。
return true;
}
return false;
}
複製程式碼
- 該方法接受key和value作為引數。如果key和value存在,那麼我們獲取表示key的字串。
- 建立一個新的鍵值對並將其賦值給table物件上的key屬性。
- 為了在字典中儲存value,我們將key轉化為了字串,而為了儲存資訊的需要,我們同樣要儲存原始的key。我們不能只將value儲存在字典中,而是要儲存兩個值:原始的key和value。所以需要再另外建立一個ValuePair類來作為值。
- 為了字典能更簡單的通過toString方法輸出結果,我們同樣要為ValuePair類建立toString方法(簡單的轉換,為物件時未處理)
- 如果key value是合法的,返回true,表示可以儲存下來。反之,返回false。
- remove() 從字典中移除一個值
remove(key) {
if (this.hasKey(key)) { // 如果字典中找到相同的key
delete this.table[this.toStrFn(key)]; // 刪除之
return true; // 如果能刪返回true
}
return false; // 否則返回false
}
複製程式碼
- get() 從字典中檢索一個值
get(key) {
const valuePair = this.table[this.toStrFn(key)];
return valuePair == null ? undefined : valuePair.value;
}
複製程式碼
- 首先檢索table是否有此key,如果有,返回此物件的value。反之返回undefined。
- keyValues() 返回字典中的所有鍵值對
keyValues() {
return Object.values(this.table); // 執行Object類內建的values方法(ECMAScript2017)
}
複製程式碼
- keys()將所有鍵名以陣列形式返回
keys() {
return this.keyValues().map(valuePair => valuePair.key); // 嗯~ 沒啥好解釋的
}
複製程式碼
- values() 將所有值以陣列形式返回
values() {
return this.keyValues().map(valuePair => valuePair.value);
}
複製程式碼
- forEatch(callbackFn) 迭代字典中的每個鍵值對
forEach(callbackFn) {
const valuePairs = this.keyValues(); // 獲取所有valuePairs構成的陣列
for (let i = 0; i < valuePairs.length; i++) { // 迭代每個valueParir
const result = callbackFn(valuePairs[i].key, valuePairs[i].value); // 執行以引數形式傳入forEach方法的callbackFn函式
if (result === false) {// 如果回撥引數返回false,會中斷forEatch方法的執行,打斷正在迭代valuePairs的for迴圈
break;
}
}
}
複製程式碼
- clear、size、isEmpty和toString方法
isEmpty() { // 字典是否為空
return this.size() === 0;
}
size() { // 返回字典所包含的數量
return Object.keys(this.table).length;
}
clear() { // 清空
this.table = {};
}
toString() { // 轉字串
if (this.isEmpty()) {
return '';
}
const valuePairs = this.keyValues();
let objString = `${valuePairs[0].toString()}`;
for (let i = 1; i < valuePairs.length; i++) {
objString = `${objString},${valuePairs[i].toString()}`;
}
return objString;
}
複製程式碼
使用字典
- 要使用Dictionary類,首先需要建立一個例項,然後給它新增三條電子郵件地址。來實現一個電子郵件地址簿。
const dictionary = new Dictionary();
dictionary.set('Gandalf', 'gandalf@email.com'); // 新增
dictionary.set('John', 'johnsnow@email.com');// 新增
dictionary.set('Tyrion', 'tyrion@email.com');// 新增
console.log(dictionary.hasKey('Gandalf')); // true
console.log(dictionary.size()); // 3
console.log(dictionary.keys()); // ["Gandalf", "John", "Tyrion"]
console.log(dictionary.values()); // ["gandalf@email.com", "johnsnow@email.com", "tyrion@email.com"]
console.log(dictionary.get('Tyrion')); // tyrion@email.com
dictionary.remove('John');
console.log(dictionary.keys()); // ["Gandalf", "Tyrion"]
console.log(dictionary.values()); // ["gandalf@email.com", "tyrion@email.com"]
console.log(dictionary.keyValues()); // [{key: "Gandalf", value: "gandalf@email.com"}, {key: "Tyrion", value: "tyrion@email.com"}]
console.log(dictionary.toString()); // [#Gandalf: gandalf@email.com],[#Tyrion: tyrion@email.com]
dictionary.forEach((k, v) => {
console.log('forEach: ', `key: ${k}, value: ${v}`);
});
// forEach: key: Gandalf, value: gandalf@email.com
// forEach: key: Tyrion, value: tyrion@email.com
複製程式碼
最後
本文內容來自本菜閱讀《Javascript資料結構與演算法》第三版第八章後,整理抄錄。碼字不易,如果覺得還可以,歡迎各位點贊!!!