@edsilv/exjs
Version:
Extension library
95 lines (88 loc) • 3.44 kB
text/typescript
/// <reference path="enumerable.ts" />
namespace exjs {
function traverseEnumerator<T>(prev: IEnumerable<T>, selector: (t: T) => IEnumerable<T>): IEnumerator<T> {
var started = false;
var enstack: IEnumerator<T>[] = [];
var t: IEnumerator<T>;
var e = {
current: undefined,
moveNext (): boolean {
if (!started) {
t = prev.getEnumerator();
started = true;
} else if (t == null) {
return false;
} else {
enstack.push(t);
t = selectorEnumerator<T, T>(selector(e.current));
}
while (!t || !t.moveNext()) {
if (enstack.length < 1)
break;
t = enstack.pop();
}
e.current = t == null ? undefined : t.current;
return e.current !== undefined;
}
};
return e;
}
function traverseUniqueEnumerator<T>(prev: IEnumerable<T>, selector: (t: T)=>IEnumerable<T>, turnstile: (t: T) => boolean): IEnumerator<T> {
var started = false;
var enstack: IEnumerator<T>[] = [];
var t: IEnumerator<T>;
var e = {
current: undefined,
moveNext (): boolean {
if (!started) {
t = prev.getEnumerator();
started = true;
} else if (t == null) {
return false;
} else {
enstack.push(t);
t = selectorEnumerator<T, T>(selector(e.current));
}
do {
while (!t || !t.moveNext()) {
if (enstack.length < 1)
break;
t = enstack.pop();
}
e.current = t == null ? undefined : t.current;
} while (turnstile(e.current));
return e.current !== undefined;
}
};
return e;
}
Enumerable.prototype.traverse = function<T>(selector: any): IEnumerableEx<T> {
var e = new Enumerable<T>();
e.getEnumerator = () => traverseEnumerator(<IEnumerable<T>>this, selector);
return e;
};
Enumerable.prototype.traverseUnique = function<T>(selector: any, matcher?: (t1: T, t2: T) => boolean): IEnumerableEx<T> {
var existing: T[] = [];
var e = new Enumerable<T>();
if (matcher) {
e.getEnumerator = () => traverseUniqueEnumerator(<IEnumerable<T>>this, selector, (x: T) => {
if (existing.some(e => matcher(x, e)))
return true;
existing.push(x);
return false;
});
} else {
e.getEnumerator = () => traverseUniqueEnumerator(<IEnumerable<T>>this, selector, (x: T) => {
if (existing.indexOf(x) > -1)
return true;
existing.push(x);
return false;
});
}
return e;
};
if (List) {
List.prototype.traverse = Enumerable.prototype.traverse;
List.prototype.traverseUnique = Enumerable.prototype.traverseUnique;
}
}