Skip to content

Instantly share code, notes, and snippets.

@3AHAT0P
Created June 4, 2020 07:30
Show Gist options
  • Save 3AHAT0P/b760cfa409d6c88e720d8e5e9e56e6ec to your computer and use it in GitHub Desktop.
Save 3AHAT0P/b760cfa409d6c88e720d8e5e9e56e6ec to your computer and use it in GitHub Desktop.
It's Hash with low cost iterations
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