乐趣区

JavaScript数据结构与算法六字典

上一节,我们学习了集合,本节会继续介绍跟集合类似存储唯一值得两种数据结构。在集合中,我们存储的唯一值是值,而今天介绍的两种数据结构是采用 [键,值] 的形式进行存储,只不过实现的方式不同。

字典

字典和集合很类似,集合以 [值,值] 的形式存储,而字典以 [键,值] 的形式存储,键名用来查询特定元素。字典通常用来保存对象的引用地址。在 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;
  }
退出移动版