2019-02-08 11:56:33 +01:00
|
|
|
import * as _ from 'underscore';
|
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
type KeyValue<V> = { k: string; v: V };
|
|
|
|
type Items<V> = {
|
|
|
|
[key: string]: KeyValue<V>;
|
2019-05-31 07:15:00 +02:00
|
|
|
};
|
2019-02-08 11:56:33 +01:00
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
export class Dict<V> {
|
|
|
|
private _items: Items<V> = {};
|
2019-02-08 11:56:33 +01:00
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
get(key: string): V | undefined {
|
2019-02-08 11:56:33 +01:00
|
|
|
const mapping = this._items[this._munge(key)];
|
|
|
|
if (mapping === undefined) {
|
2019-03-25 15:55:39 +01:00
|
|
|
return undefined;
|
2019-02-08 11:56:33 +01:00
|
|
|
}
|
|
|
|
return mapping.v;
|
|
|
|
}
|
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
set(key: string, value: V): V {
|
2019-02-08 11:56:33 +01:00
|
|
|
this._items[this._munge(key)] = {k: key, v: value};
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
has(key: string): boolean {
|
2019-02-08 11:56:33 +01:00
|
|
|
return _.has(this._items, this._munge(key));
|
|
|
|
}
|
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
del(key: string): void {
|
2019-03-27 11:11:20 +01:00
|
|
|
delete this._items[this._munge(key)];
|
2019-02-08 11:56:33 +01:00
|
|
|
}
|
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
keys(): string[] {
|
2019-02-08 11:56:33 +01:00
|
|
|
return _.pluck(_.values(this._items), 'k');
|
|
|
|
}
|
|
|
|
|
|
|
|
values(): V[] {
|
|
|
|
return _.pluck(_.values(this._items), 'v');
|
|
|
|
}
|
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
items(): [string, V][] {
|
2019-02-08 11:56:33 +01:00
|
|
|
return _.map(_.values(this._items),
|
2020-02-01 05:10:50 +01:00
|
|
|
(mapping: KeyValue<V>): [string, V] => [mapping.k, mapping.v]);
|
2019-02-08 11:56:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
num_items(): number {
|
|
|
|
return _.keys(this._items).length;
|
|
|
|
}
|
|
|
|
|
|
|
|
is_empty(): boolean {
|
|
|
|
return _.isEmpty(this._items);
|
|
|
|
}
|
|
|
|
|
2020-02-01 05:10:50 +01:00
|
|
|
each(f: (v: V, k?: string) => void): void {
|
|
|
|
_.each(this._items, (mapping: KeyValue<V>) => f(mapping.v, mapping.k));
|
2019-02-08 11:56:33 +01:00
|
|
|
}
|
|
|
|
|
2019-03-25 15:55:39 +01:00
|
|
|
clear(): void {
|
2019-02-08 11:56:33 +01:00
|
|
|
this._items = {};
|
|
|
|
}
|
2019-03-25 15:55:39 +01:00
|
|
|
|
2019-12-26 15:34:17 +01:00
|
|
|
// Convert keys to strings and handle undefined.
|
2020-02-01 05:10:50 +01:00
|
|
|
private _munge(key: string): string | undefined {
|
2019-03-25 15:55:39 +01:00
|
|
|
if (key === undefined) {
|
|
|
|
blueslip.error("Tried to call a Dict method with an undefined key.");
|
|
|
|
return undefined;
|
|
|
|
}
|
2020-02-01 05:10:50 +01:00
|
|
|
|
|
|
|
if (typeof key !== 'string') {
|
|
|
|
blueslip.error("Tried to call a Dict method with a non-string.");
|
|
|
|
key = (key as object).toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
return ':' + key;
|
2019-03-25 15:55:39 +01:00
|
|
|
}
|
2019-02-08 11:56:33 +01:00
|
|
|
}
|