Created
June 4, 2020 07:30
-
-
Save 3AHAT0P/b760cfa409d6c88e720d8e5e9e56e6ec to your computer and use it in GitHub Desktop.
It's Hash with low cost iterations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class IterableHash<G extends string | number, T> { | |
[key: string]: T; | |
[key: number]: T; | |
// @ts-ignore | |
private primaryKeyIndex: G[] = []; | |
// @ts-ignore | |
private data: Record<G, T | void> = {}; | |
// @ts-ignore | |
public getKeys(): G[] { | |
return this.primaryKeyIndex; | |
} | |
// @ts-ignore | |
public get(key: G): T | void { | |
return this.data[key]; | |
} | |
// @ts-ignore | |
public has(key: G): boolean { | |
return key in this.data; | |
} | |
// @ts-ignore | |
public set(key: G, value: T): boolean { | |
if (!this.has(key)) this.primaryKeyIndex.push(key); | |
this.data[key] = value; | |
return true; | |
} | |
// @ts-ignore | |
public remove(key: G): boolean { | |
const index = this.primaryKeyIndex.indexOf(key); | |
this.primaryKeyIndex.splice(index, 1); | |
return delete this.data[key]; | |
} | |
public *[Symbol.iterator](): Generator<[G, T | void], { isDone: boolean, value: [G, T] } | void, void> { | |
for (let i = 0; i < this.primaryKeyIndex.length; i += 1) { | |
const key = this.primaryKeyIndex[i]; | |
yield [key, this.data[key]]; | |
} | |
} | |
} | |
const excludedKeys = ['primaryKeyIndex', 'data', 'constructor', Symbol.iterator, 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toString', 'valueOf']; | |
type Constructor<T = object> = new (...args: any[]) => T; | |
const IterableHashProxy = new Proxy(IterableHash, { | |
construct<G extends string | number, T>(target: Constructor<IterableHash<G, T>>, args: any[]) { | |
const instance = new target(...args); | |
const proxy = new Proxy(instance, { | |
get(target, key: G, reciever) { | |
console.log(key.toString()); | |
if (excludedKeys.includes(key)) return target[key]; | |
return target.get(key); | |
}, | |
has(target, key: G) { | |
console.log(key.toString()); | |
if (excludedKeys.includes(key)) return false; | |
return target.has(key); | |
}, | |
set(target, key: G, value, reciever) { | |
if (excludedKeys.includes(key)) return false; | |
return target.set(key, value); | |
}, | |
deleteProperty(target, key: G) { | |
if (excludedKeys.includes(key)) return false; | |
return target.remove(key); | |
}, | |
getOwnPropertyDescriptor(target, key: G): PropertyDescriptor | undefined { | |
return void 0; | |
}, | |
ownKeys(target): G[] { | |
return target.getKeys(); | |
}, | |
defineProperty(target, key: G, propertyDescriptor: PropertyDescriptor): boolean { | |
return false; | |
} | |
}); | |
return proxy; | |
} | |
}) | |
// const proxyHash = new IterableHashProxy<string, number>(); | |
// console.log( | |
// proxyHash.a = 42, | |
// proxyHash['4'] = 4, | |
// proxyHash['3'] = -3, | |
// ); | |
// console.log(proxyHash); | |
// console.log(proxyHash.a, proxyHash['3'], proxyHash.ads); | |
// delete proxyHash['3']; | |
// for (const [key, value] of proxyHash) console.log(key, value); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment