上一节,我们学习了集合,本节会继续介绍跟集合类似存储唯一值得两种数据结构。在集合中,我们存储的唯一值是值,而今天介绍的两种数据结构是采用 [键,值] 的形式进行存储,只不过实现的方式不同。
字典
字典和集合很类似,集合以 [值,值] 的形式存储,而字典以 [键,值] 的形式存储,键名用来查询特定元素。字典通常用来保存对象的引用地址。在 ES2015 同样包含了 Map 类的实现。实际生活中也有字典的不少应用,比如电话本,地址簿,词典。好了,接下来用代码实现字典:
创建字典类
// 由于理想情况下,字典的键名都必须是字符串,值的话可以任意类型
function defaultToString(item) {if (item === null) {return 'NULL';} if (item === undefined) {return 'UNDEFINED';} if (typeof item === 'string' || item instanceof String) {return `${item}`;
}
return item.toString();};
//Ditionary 骨架
class Dictionary {constructor(toStrFn = defaultToString) {
this.toStrFn = toStrFn;
this.table = {};}
检测一个键是否存在于字典中
hasKey(key) {return this.table[this.toStrFn(key)] != null;
}
向字典中添加新元素或者更新元素
// 用来保存[key,value], 因为信息的重要性,所以原始数据也需要保存,而不能只存储在字典中
class ValuePair {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);
this.table[tableKey] = new ValuePair(key, value);
return true;
}
return false;
}
从字典中删除元素
remove(key) {if (this.hasKey(key)) {delete this.table[this.toStrFn(key)];
return true;
}
return false;
}
从字典中检索一个值
get(key) {const valuePair = this.table[this.toStrFn(key)];
return valuePair == null ? undefined : valuePair.value;
};
// 第二种方法,不过不推荐使用,因为遍历了两次,消耗大
get(key){if (this.hasKey(key)) {return this.table[this.toStrFn(key)];
};
return undefined;
}
辅助方法
以下代码基于 ES2015 以上的语法实现
从 table 对象中得到所有对象
keyValues() {return Object.values(this.table);
}
以上以数组形式返回字典中所有 valuePair 对象
返回所有用于识别值的所有(原始)键名构成的数组
keys() {return this.keyValues().map(valuePair => valuePair.key);
}
返回字典中所有的值组成的数组
values() {return this.keyValues().map(valuePair => valuePair.value);
}
使用 forEach 迭代字典中的每个键值对
forEach(callbackFn) {const valuePairs = this.keyValues();
for (let i = 0; i < valuePairs.length; i++) {const result = callbackFn(valuePairs[i].key, valuePairs[i].value);
if (result === false) {break;}
}
}
返回字典中的值的个数
size() {return Object.keys(this.table).length;
}
检验字典是否为空
isEmpty() {return this.size() === 0;
}
清空字典内容
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;
}