Skip to content

Instantly share code, notes, and snippets.

@felixfbecker
Last active April 19, 2018 07:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save felixfbecker/7751a3b30a5a28a1cb4b8149571c99e8 to your computer and use it in GitHub Desktop.
Save felixfbecker/7751a3b30a5a28a1cb4b8149571c99e8 to your computer and use it in GitHub Desktop.
Immutable __proto__ backed Map
// tslint:disable:forin
export class ProtoMap<V> {
private _values: any;
public [Symbol.toStringTag]: 'ProtoMap' = 'ProtoMap'
constructor(init?: Iterable<[string, V]> | { [key: string]: V }) {
this._values = { __proto__: null }
if (init) {
if (typeof (init as any)[Symbol.iterator] === 'function') {
for (const [key, value] of init as Iterable<[string, V]>) {
this._values[key] = value
}
} else {
this._values = init
}
}
}
public get(key: string): V | undefined {
return this._values[key]
}
public has(key: string): boolean {
return key in this._values
}
public with(key: string, value: V): ProtoMap<V> {
return new ProtoMap({ __proto__: this._values, [key]: value })
}
public [Symbol.iterator](): IterableIterator<[string, V]> {
return this.entries()
}
public *entries(): IterableIterator<[string, V]> {
for (const key in this._values) {
yield [key, this._values[key]]
}
}
public *values(): IterableIterator<V> {
for (const key in this._values) {
yield this._values[key]
}
}
public *keys(): IterableIterator<string> {
for (const key in this._values) {
yield key
}
}
public forEach(callback: (value: V, key: string, map: ProtoMap<V>) => void): void {
for (const key in this._values) {
callback(this._values[key], key, this)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment