import { create, has, ObjectLike } from '../../core/object'; import { isIterable, isArrayLike, isObject } from '../../core/traits'; //! \todo add 'symbol' here (or change to PropertyKey) when https://github.com/Microsoft/TypeScript/pull/26797 will be ready export type FastKey = number | string; /*! \class FastMap \brief Wrapper around native object with Map-like interface. */ export class FastMap { protected _entries = create(); protected _size: number = 0; constructor(entries?: ArrayLike<[FastKey, V]> | Iterable<[FastKey, V]>) { if (isIterable(entries)) { for (const [key, value] of entries) this.set(key, value); } else if (isArrayLike(entries)) { for (let i = 0; i < entries.length; i++) { const [key, value] = entries[i]; this.set(key, value); } } } get size() { return this._size; } get(key: FastKey) { return this._entries[key]; } set(key: FastKey, value: V) { if (!this.has(key)) this._size++; this._entries[key] = value; return this; } has(key: FastKey) { return has(this._entries, key); } delete(key: FastKey) { if (this.has(key)) { this._size--; delete this._entries[key]; return true; } return false; } clear() { for (const key of this.keys()) this.delete(key); } *keys() { const entries = this._entries; for (const key in entries) yield key; } *values() { const entries = this._entries; for (const key in entries) yield entries[key] as V; } *entries() { const entries = this._entries; for (const key in entries) yield [key, entries[key]] as [string, V]; } forEach(callbackfn: (value: V, key: string, map: FastMap) => void, thisArg?: any) { for (const key in this._entries) callbackfn.call(thisArg, this._entries[key], key, this); } [Symbol.iterator]() { return this.entries(); } reset(entries?: ObjectLike) { this.clear(); if (isObject(entries)) for (const key in entries) if (has(entries, key)) this.set(key, entries[key]); } }