web-atoms-core
Version:
91 lines (77 loc) • 2.65 kB
text/typescript
if (typeof Map === "undefined") {
interface IKeyValuePair<K, V> {
key: K;
value: V;
}
class AtomMap<K, V> {
public get size(): number {
return this.map.length;
}
private map: Array<IKeyValuePair<K, V>> = [];
public clear(): void {
this.map.length = 0;
}
public delete(key: K): boolean {
return this.map.remove((x) => x.key === key);
}
public forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void {
for (const iterator of this.map) {
callbackfn.call(thisArg, iterator.value, iterator.key, this);
}
}
public get(key: K): V {
const item = this.getItem(key, false);
return item ? item.value : undefined;
}
public has(key: K): boolean {
return this.map.find((x) => x.key === key) != null;
}
public set(key: K, value: V): this {
const item = this.getItem(key, true);
item.value = value;
return this;
}
// public [Symbol.iterator](): IterableIterator<[K, V]> {
// throw new Error("Method not implemented.");
// }
// public keys(): IterableIterator<K> {
// throw new Error("Method not implemented.");
// }
// public values(): IterableIterator<V> {
// throw new Error("Method not implemented.");
// }
// public get [Symbol.toStringTag](): string {
// return "[Map]";
// }
private getItem(key: K, create: boolean = false): IKeyValuePair<K, V> {
for (const iterator of this.map) {
if (iterator.key === key) {
return iterator;
}
}
if (create) {
const r = { key, value: undefined };
this.map.push(r);
return r;
}
}
}
// tslint:disable-next-line:no-string-literal
(window as any)["Map"] = AtomMap;
}
declare global {
// tslint:disable-next-line:interface-name
interface Map<K, V> {
getOrCreate(key: K, factory: (key: K) => V): V;
}
}
// tslint:disable-next-line:only-arrow-functions
Map.prototype.getOrCreate = function(key: any, factory: (key: any) => any): any {
let item = this.get(key);
if (item === undefined) {
item = factory(key);
this.set(key, item);
}
return item;
};
export default Map;