字典是一种以 - 对形式存储结构的数据结构, 就像电话号码薄里的名字和电话号码一样. 要找一个电话时, 先找名字, 名字找到了, 紧挨着它的电话号码也就找到了. 这里的 是指你用来查找的东西, 是查找得到的结果.
JSObject类就是以字典形式设计的. 本章将使用Object类本身的特性, 实现一个Dictionary类, 让这种字典类型的对象使用起来更加简单. 你也可以只使用数组和对象来实现本章展示的方法, 但是定义一个Dictionary类更方便, 也更有意思. 比如, 使用()引用键就比使用[]简单. 当然, 还有其他一些便利, 比如可以定义对整体进行操作的方法, 举个栗子, 显示字典中所有的元素, 这样就不必在主程序中循环去遍历字典了.

Dictionary

Dictionary类是基础是Array类, 而不是Object类. 本章稍后将提到, 我们想对字典中的键排序, 而JS中是不能对对象的属性进行排序的. 但是也不要忘记, JS中一切皆对象, 数组也是对象.

window.log = console.log.bind(console)

class Dictionary {
    constructor() {
        this._datastore = [];
    }
    add(key, value) {
        this._datastore[key] = value;
    }
    find(key) {
        return this._datastore[key];
    }
    remove(key) {
        delete this._datastore[key];
    }
    showAll() {
        Object.keys(this._datastore).forEach(key => {
            log(`${key}  ===>>>   ${this._datastore[key]}`)
        })
    }
};

const pbook = new Dictionary();
pbook.add('作家1', '书1');
pbook.add('作家2', '书2');
pbook.add('作家3', '书3');
pbook.add('作家4', '书4');
pbook.showAll();
log('</br>')
pbook.remove('作家3');
pbook.showAll();

add()方法接受两个参数: 键和值. 键是值在字典中索引.
find()方法以键为参数, 返回和其相关联的值.
remove()方法用到了JS中的一个内置函数: delete.该函数是Object类的一部分, 使用对键的引用作为参数. 该函数同时删掉键和与其关联的值.
showAll()方法显示字典中所有的键值对.

Dictionary类的辅助方法

我们还可以定义一些在特定情况下用的辅助方法.

...
count() {
    let n = 0;
    Object.keys(this._datastore).forEach(i => {
        n++
    });
    
    return n;
}
clear() {
    Object.keys(this._datastore).forEach(key => {
        delete this._datastore[key]
    });
}
...

比如, 要是能知道字典中的元素个数就好了, 那么就可以定义一个count()方法.
这里你可能就要问了, 既然_datastore是数组类型的话为什么不直接用length属性呢? 这是因为当键的类型为字符串时, length属性就不管用了. eg:

const nums = [];
nums[0] = 1;
nums[1] = 2;
log(nums.length); // 2

const book = [];
book['a'] = 1;
book['b'] = 2;
log(book.length); // 0

以及清空字典clear(). 这里使用this._datastore = []也是可以的;

Dictionary类添加排序功能

字典的主要用途是通过键取值, 我们无需太关心数据在字典中的实际存储顺序. 然而, 很多人都希望看到一个有序的字典. 下面来看看如何让前面的字典按顺序显示.

数组是可以排序的, eg:

const a = [];
a[0] = 'm';
a[1] = 'd';
log(a); // m d

a.sort();
log(a); // d m

但是上面的这种做法是对字符串作为键的字典无效的, 程序会没有任何输出. 这和我们前面定义count()方法时情况一致;

不过这也不是大问题. 用户关心的是显示字典的内容时, 结果是有序的. 可使用Object.keys()函数解决这个问题, 重新定义showAll()方法:

showAll() {
    Object.keys(this._datastore).sort().forEach(key => {
        log(`${key}  ===>>>   ${this._datastore[key]}`)
    })
}

和前面的区别是: 拿到_datastore的键后, 调用sort()方法对键重新排序.


伍陆柒
1.2k 声望25 粉丝

如果觉得我的文章对大家有用的话, 可以去我的github start一下[链接]