-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
59 lines (52 loc) · 1.71 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
const kvp_symbol = Symbol();
export function decorateIterableObject(obj: any, dir?: 'desc' | 'asc', returnKvp?: boolean) {
obj[kvp_symbol] = !!returnKvp;
if (!dir) {
obj[Symbol.iterator] = getNext;
} else if ('desc' === dir) {
obj[Symbol.iterator] = getNextDesc;
} else {
obj[Symbol.iterator] = getNextAsc;
}
return obj;
}
function* getNext(this: any): IterableIterator<string | IKeyValuePair> {
if (this[kvp_symbol]) {
for (const k in this)
if (this.hasOwnProperty(k)) yield {key: k, value: this[k]};
} else
for (const k in this)
if (this.hasOwnProperty(k)) yield k;
}
function* getNextDesc(this: any): IterableIterator<string | IKeyValuePair> {
yield* loopThroughKeys.call(this, Object.keys(this).sort((a, b) => {
if (a > b) return -1;
else return (a < b) as any;
}));
}
function* getNextAsc(this: any): IterableIterator<string | IKeyValuePair> {
yield* loopThroughKeys.call(this, Object.keys(this).sort());
}
function* loopThroughKeys(this: any, keys: string[]): IterableIterator<string | IKeyValuePair> {
if (this[kvp_symbol])
for (const k of keys) yield {key: k, value: this[k]};
else
for (const k of keys) yield k;
}
export function Iterable(dir?: 'desc' | 'asc', returnKvp?: boolean): (target: any, propertyKey: string) => void {
return function (this: any, target: any, propertyKey: string): void {
const s = Symbol();
Object.defineProperty(target.constructor.prototype, propertyKey, <PropertyDescriptor>{
set(this: any, val: any): void {
this[s] = decorateIterableObject(val, dir, returnKvp);
},
get(this: any): any {
return this[s];
}
});
};
}
export interface IKeyValuePair {
key: string,
value: any
}