@edsilv/exjs
Version:
Extension library
76 lines (66 loc) • 3.44 kB
text/typescript
/// <reference path="enumerable.ts" />
namespace exjs {
function orderByEnumerable<T, TKey>(source: IEnumerable<T>, keySelector: (t: T) => TKey, isDescending: boolean, comparer?: (f: TKey, s: TKey) => number): IOrderedEnumerable<T> {
return new OrderedEnumerable<T, TKey>(source, keySelector, isDescending, comparer);
}
class OrderedEnumerable<T, TKey> extends Enumerable<T> implements IOrderedEnumerable<T> {
Source: IEnumerable<T>;
Sorter: (a: T, b: T) => number;
constructor (source: IEnumerable<T>, keySelector: (t: T) => TKey, isDescending: boolean, keyComparer: (f: TKey, s: TKey) => number) {
super();
this.Source = source;
keyComparer = keyComparer || function (f: TKey, s: TKey) {
return f > s ? 1 : (f < s ? -1 : 0);
};
var factor = (isDescending === true) ? -1 : 1;
this.Sorter = (a, b) => factor * keyComparer(keySelector(a), keySelector(b));
}
getEnumerator (): IEnumerator<T> {
var source = this.Source;
var sorter = this.Sorter;
var arr: T[];
var i = 0;
var e = {
current: undefined,
moveNext: function (): boolean {
if (!arr) {
arr = en(source).toArray();
arr.sort(sorter);
}
e.current = undefined;
if (i >= arr.length)
return false;
e.current = arr[i];
i++;
return true;
}
};
return e;
}
thenBy<TInnerKey>(keySelector: (t: T) => TInnerKey, comparer?: (f: TInnerKey, s: TInnerKey) => number): IOrderedEnumerable<T> {
return new ThenEnumerable<T, TKey, TInnerKey>(this, keySelector, false, comparer);
}
thenByDescending<TInnerKey>(keySelector: (t: T) => TInnerKey, comparer?: (f: TInnerKey, s: TInnerKey) => number): IOrderedEnumerable<T> {
return new ThenEnumerable<T, TKey, TInnerKey>(this, keySelector, true, comparer);
}
}
class ThenEnumerable<T, TParentKey, TKey> extends OrderedEnumerable<T, TKey> {
constructor (source: OrderedEnumerable<T, TParentKey>, keySelector: (t: T) => TKey, isDescending: boolean, keyComparer: (f: TKey, s: TKey) => number) {
super(source, keySelector, isDescending, keyComparer);
var parentSorter = source.Sorter;
var thisSorter = this.Sorter;
this.Sorter = (a, b) => parentSorter(a, b) || thisSorter(a, b);
}
}
var fn = Enumerable.prototype;
fn.orderBy = function<T,TKey>(keySelector: (t: T) => TKey, comparer?: (f: TKey, s: TKey) => number): IOrderedEnumerable<T> {
return orderByEnumerable(<IEnumerable<T>>this, keySelector, false, comparer);
};
fn.orderByDescending = function<T,TKey>(keySelector: (t: T) => TKey, comparer?: (f: TKey, s: TKey) => number): IOrderedEnumerable<T> {
return orderByEnumerable(<IEnumerable<T>>this, keySelector, true, comparer);
};
if (List) {
List.prototype.orderBy = Enumerable.prototype.orderBy;
List.prototype.orderByDescending = Enumerable.prototype.orderByDescending;
}
}