基本概念
字典是用来存储【键-值】对的数据结构,键名用来查询特定元素。与集合类似,只不过集合是以【值-值】的形式存储元素。字典也被称作映射、符号表或关联数组。
实现
import { defaultToString } from "../utils/toString";
class ValuePair {
key: any;
value: any;
constructor(key: any, value: any) {
this.key = key;
this.value = value;
}
toString() {
return `${defaultToString(this.key)}: ${defaultToString(this.value)}`;
}
}
export class Map {
toStringFun: (key: any) => string;
table: object; // 存储字典数据
constructor(toStringFun = defaultToString) {
this.toStringFun = toStringFun;
this.table = {};
}
// hasKey 方法,用于判断字典中是否包含某元素
hasKey(key: any): boolean {
return this.table[key] != null; // 这里用不等于,方便判断null和undefined两种情况
}
// set方法,给字典中添加元素
set(key: any, value: any) {
if (key != null && value != null) {
// ValuePair类,是因为我们为了能够在字典中存储元素,将key转为了字符串,而为了保存完整信息的必要性,我们需要将原始的key也保存
this.table[this.toStringFun(key)] = new ValuePair(key, value);
return true; // 添加成功
}
return false; // 添加失败
}
// remove方法,移除字典中的一个元素
remove(key: any) {
if (this.hasKey(key)) {
delete this.table[this.toStringFun(key)];
return true;
}
return false;
}
// get方法,获取字典中的一个元素
get(key: any) {
const res = this.table[this.toStringFun(key)];
return res == null ? undefined : res.value;
}
// keyValues方法,以数组形式返回当前字典的值
keyValues() {
return Object.values(this.table);
// 如果浏览器不支持Object.values,那么可以使用for...in循环来实现
// const valuePairs = [];
// for (const key in this.table) {
// if (this.hasKey(key)) {
// valuePairs.push(this.table[key]);
// }
// }
// return valuePairs;
}
// keys方法,已数组形式返回当前字典的原始键
keys() {
return this.keyValues().map((value) => value.key);
}
// values方法,以数组形式返回当前字典的value
values() {
return this.keyValues().map((value) => value.value);
}
// 很多时候我们需要遍历出来全部的元素进行处理,所以这里我们模拟forEach方法
forEach(callback: (key: any, value: any) => any) {
const values = this.keyValues();
for (let i = 0; i < values.length; i++) {
const result = callback(values[i].key, values[i].value);
if (result === false) {
break; // 这里如果回调函数返回false,我们终止循环
}
}
}
// size方法,返回当前字典的元素数量
size() {
return Object.keys(this.table).length;
// 当然也可以调用我们前面写好的keyValues方法
// return this.keyValues().length;
}
// isEmpty方法,返回当前字典是否为空
isEmpty() {
return this.size() === 0;
}
// clear方法,清空当前字典
clear() {
this.table = {};
}
// toString方法
toString() {
if (this.isEmpty()) {
return "";
}
const values = this.keyValues();
let resultStr = `${values[0].toString()}`;
for (let i = 1; i < values.length; i++) {
resultStr += `;${values[i].toString()}`;
}
return resultStr;
}
}
export function defaultToString<T>(arr: T): string {
if (arr === null) {
return "NULL";
} else if (arr === undefined) {
return "UNDEFINED";
} else if (typeof arr === "string" || arr instanceof String) {
return `${arr}`;
} else {
return JSON.stringify(arr);
}
}