UNPKG

nowjs-core

Version:

NowCanDo Javascript Core [nowjs-core] is a library written by TypeScript code maintains under Apache 2.0 licence

936 lines (935 loc) 30.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const index_1 = require("../exceptions/index"); const Collectors_1 = require("../collections/Collectors"); const List_1 = require("../collections/List"); const Collection_1 = require("../collections/Collection"); const ObjectUtils_1 = require("../utils/ObjectUtils"); class Enumerable { constructor(enumerable, options) { this.enumerable = enumerable; this.options = options; if (!enumerable) enumerable = []; this.options = options || {}; } collect(factory) { factory = factory || Collectors_1.Collectors.toIEnumerable(); return factory(this.enumerable); } static from(enumerable) { return new Enumerable(enumerable); } static repeat(result, count) { const itr = { [Symbol.iterator]: () => { let counter = 0; return { next: () => { if (counter < count) { counter++; return { value: typeof result === 'function' ? result.apply(result) : result, done: false, }; } else { return { done: true }; } }, }; }, }; return new Enumerable(itr); } static range(start, count, step = 1) { const itr = { [Symbol.iterator]: () => { let curr = start - 1; let counter = 0; return { next: () => { if (counter >= count) { return { done: true }; } else { counter++; curr += step; return { value: curr, done: false }; } }, }; }, }; return new Enumerable(itr); } static comparator(a, b) { if (a === b) { return 0; } else if (a > b) { return 1; } else { return -1; } } static equalityComparator(a, b) { return a === b ? 0 : -1; } static selector(t) { return t; } aggregate(action, seed) { const arr1 = this.toArray(); if (seed == null) seed = arr1.shift(); for (let i = 0; i < arr1.length; i++) { seed = action(seed, arr1[i], i, this); } return seed; } all(predicate) { for (const xx of this.enumerable) { if (predicate(xx) === false) { return false; } } return true; } any(predicate) { for (const xx of this) { if (predicate(xx) === true) { return true; } } return false; } first(predicate, defValue) { defValue = defValue ? defValue : null; for (const xx of this.enumerable) { if (predicate) { if (predicate(xx) === true) { return xx; } } else { return xx; } } return defValue; } last(predicate, defValue) { defValue = defValue ? defValue : null; for (const xx of this.enumerable) { if (predicate) { if (predicate(xx) === true) { defValue = xx; } } else { defValue = xx; } } return defValue; } single(predicate, defValue) { defValue = defValue ? defValue : null; for (const xx of this.enumerable) { if (predicate) { if (predicate(xx) === true) { return xx; } } else { return xx; } } return defValue; } contains(item) { for (const x of this) { if (x === item) { return true; } } return false; } isEmpty() { if (this.enumerable && this.enumerable[Symbol.iterator]) { return this.enumerable[Symbol.iterator]().next().done; } return true; } skip(count) { const thisme = this; const itr = { [Symbol.iterator]: () => { const enb = thisme.enumerable[Symbol.iterator](); for (let i = 0; i < count; i++) { enb.next(); } return { next: () => { return enb.next(); }, }; }, }; return new Enumerable(itr); } skipWhile(predicate) { const thisme = this; const itr = { [Symbol.iterator]: () => { let xx; const enb = thisme.enumerable[Symbol.iterator](); do { xx = enb.next(); if (xx && predicate(xx.value) === true) { return { next: () => { if (xx) { const yy = xx; xx = null; return yy; } return enb.next(); }, }; } } while (xx.done === false); }, }; return new Enumerable(itr); } take(count) { const thisme = this; const itr = { [Symbol.iterator]: () => { let i = 0; const enb = thisme.enumerable[Symbol.iterator](); return { next: () => { const x = enb.next(); if (i === count) { x.done = true; } i++; return x; }, }; }, }; return new Enumerable(itr); } takeWhile(predicate) { const thisme = this; const itr = { [Symbol.iterator]: () => { let xx; const enb = thisme.enumerable[Symbol.iterator](); return { next: () => { xx = enb.next(); if (xx && predicate(xx.value) === true) { xx.done = true; } return xx; }, }; }, }; return new Enumerable(itr); } distinct() { const thisme = this; const itr = { [Symbol.iterator]: () => { const enb = thisme.enumerable[Symbol.iterator](); const traversed = new Set(); return { next: () => { while (true) { const item = enb.next(); if (item.done === true) { return item; } if (!traversed.has(item.value)) { traversed.add(item.value); return item; } } }, }; }, }; return new Enumerable(itr); } reverse() { const revIt = this.toArray().reverse(); return new Enumerable(revIt); } shuffles(count) { const thisme = this; const arr = this.toArray(); const res = []; const mrands = Enumerable.repeat(() => { return Math.floor(Math.random() * arr.length); }, count); for (const item of mrands) { res.push(arr[item]); } return new Enumerable(res); } asEnumerable() { return new Enumerable(this.enumerable); } select(selector) { const thisme = this; const itr = { [Symbol.iterator]: () => { const enb = thisme.enumerable[Symbol.iterator](); return { next: () => { const nx = enb.next(); if (nx.done === false) { nx.value = selector ? selector(nx.value) : nx.value; } return nx; }, }; }, }; return new Enumerable(itr); } selectMany(selector, collectionSelector) { const thisme = this; const itr = { [Symbol.iterator]: () => { const itr1 = thisme.enumerable[Symbol.iterator](); let citer = null; const itm = () => { if (!citer) { const pnv = itr1.next(); if (pnv && pnv.done === false) { if (selector) { const childv = selector(pnv.value); if (childv && childv[Symbol.iterator]) { citer = childv[Symbol.iterator](); } } } else { return pnv; } } if (citer) { const nv = citer.next(); if (nv.done === false) { if (collectionSelector) { return { value: collectionSelector(nv.value), done: nv.done }; } else { return nv; } } else { citer = null; return itm(); } } }; return { next: () => { return itm(); }, }; }, }; return new Enumerable(itr); } indexOf(item) { let indx = -1; for (const xx of this) { indx++; if (xx === item) { return indx; } } return -1; } lastIndexOf(item) { let indx = -1; let findex = -1; for (const xx of this) { indx++; if (xx === item) { findex = indx; } } return findex; } join(inner, outerSelector, innerSelector, resultSelector) { const itr = { [Symbol.iterator]: () => { const enbOuter = this[Symbol.iterator](); let enbg; const getGroup = (groups, key) => { if (!enbg) { enbg = groups[Symbol.iterator](); } while (true) { const ixg = enbg.next(); if (ixg.done === false && ixg.value && ixg.value.key === key) { return ixg.value; } if (ixg.done === true) { return null; } } }; const ig = new Enumerable(inner).groupBy(innerSelector); let oit; let xOuter; return { next: () => { if (oit) { const g = oit.next(); if (g.done === false) { const xx = { done: false, value: resultSelector(xOuter.value, g.value), }; return xx; } else { oit = null; } } xOuter = enbOuter.next(); if (xOuter && xOuter.done === false) { const og = getGroup(ig, outerSelector(xOuter.value)); if (og) { oit = og.values[Symbol.iterator](); if (oit) { const g = oit.next(); if (g.done === false) { const xx = { done: false, value: resultSelector(xOuter.value, g.value), }; return xx; } else { oit = null; } } } } return { done: true }; }, }; }, }; return new Enumerable(itr); } where(predicate) { const thisme = this; const itr = { [Symbol.iterator]: () => { const enb = thisme[Symbol.iterator](); const getNext = () => { let xx; do { xx = enb.next(); if (xx && xx.done === false && predicate(xx.value) === true) { break; } } while (xx.done === false); return xx; }; return { next: () => { if (predicate) { return getNext(); } else { return enb.next(); } }, }; }, }; return new Enumerable(itr); } except(predicate) { const thisme = this; const itr = { [Symbol.iterator]: () => { let xx; const enb = thisme.enumerable[Symbol.iterator](); return { next: () => { xx = enb.next(); if (xx && predicate(xx.value) === true) { do { xx = enb.next(); if (xx && predicate(xx.value) === false) { break; } } while (xx.done === false); } return xx; }, }; }, }; return new Enumerable(itr); } orderBy(selector, comparator) { comparator = comparator || Enumerable.comparator; selector = selector || ((xx) => xx); const cmp = (a, b) => { return comparator(selector(a), selector(b)); }; const enb = this[Symbol.iterator](); let arr = this.toArray(); arr = arr.sort(cmp); return new OrderedEnumerable(arr); } orderByDesc(selector, comparator) { comparator = comparator || Enumerable.comparator; return this.orderBy(selector, (a, b) => { return -comparator(a, b); }); } internalGroupBy(source, keySelector, parentKey) { const groups = new Map(); for (const item of source) { if (item.key && item.values) { const gitems = this.internalGroupBy(item.values, keySelector, item.key); for (const gitem of gitems) { const s = groups.get(gitem.key); if (s) { const lis = []; for (const li of gitem.values) { lis.push(li); } for (const si of s) { lis.push(si); } gitem.values = new Enumerable(lis); } else { groups.set(gitem.key, gitem.values); } } } else { const key = parentKey ? keySelector({ key: item }) : keySelector(item); let flist = null; if (typeof key === 'object') { for (const [k, v] of groups.entries()) { if (ObjectUtils_1.deepEqual(key, k)) { flist = v; break; } } } else { flist = groups.get(key); } if (flist) { flist.push(item); } else { const lst = []; lst.push(item); groups.set(key, lst); } } } const list = []; groups.forEach((v, k) => { list.push({ key: k, values: new Enumerable(v) }); }); return new Enumerable(list); } groupBy(keySelector) { return this.internalGroupBy(this, keySelector); } count(predicate) { let i = -1; for (const xx of this) { if (predicate) { if (predicate(xx)) { i++; } } else { i++; } } return i + 1; } average(selector, predicate) { let res = 0; let count = 0; for (const x of this.enumerable) { const xx = selector ? selector(x) : x; if (selector && predicate) { if (predicate(xx) === true) { res += xx; count++; } } else { res += xx; count++; } } return res / count; } max(selector, predicate) { let res = selector ? selector(this.first()) : this.first(); for (const x of this) { const xx = selector ? selector(x) : x; if (selector && predicate) { if (predicate(xx) === true) { if (Enumerable.comparator(xx, res) === 1) { res = xx; } } } else { if (Enumerable.comparator(xx, res) === 1) { res = xx; } } } return res; } min(selector, predicate) { let res; for (const x of this) { const xx = selector ? selector(x) : x; if (selector && predicate) { if (predicate(xx) === true) { if (Enumerable.comparator(xx, res) === -1) { res = xx; } } } else { if (Enumerable.comparator(xx, res) === -1) { res = xx; } } } return res; } sum(selector, predicate) { let res = 0; for (const x of this) { const xx = selector ? selector(x) : x; if (selector && predicate) { if (predicate(xx) === true) { res += xx; } } else { res += xx; } } return res; } stdDev(selector, predicate) { const source = this.where(predicate).select(selector); const count = source.count(); const avg = source.average(); const sum = source.sum(d => (d - avg) * (d - avg)); const ret = Math.sqrt(sum / count); return ret; } stdDevP(selector, predicate) { const source = this.where(predicate).select(selector); const count = source.count(); const avg = source.average(); const sum = source.sum(d => (d - avg) * (d - avg)); const ret = Math.sqrt(sum / (count - 1)); return ret; } variance(selector, predicate) { const source = this.where(predicate).select(selector); const count = source.count(); if (count === 0) return 0; const mean = source.average(); const squareDiffs = source.select(item => { const d = item; return (d - mean) * (d - mean); }); const ret = squareDiffs.average(); return ret; } rootMeanSquare(selector, predicate) { const source = this.where(predicate).select(selector); const count = source.count(); const s = source.aggregate((x, d) => (x += Math.pow(d, 2))); return Math.sqrt(s / count); } covariance(other, selector, predicate) { const source = this.where(predicate).select(selector); const target = other.where(predicate).select(selector); const sourcecount = this.count(predicate); const sourceAvg = source.average(); const targetAvg = target.average(); let ret = 0; for (let i = 0; i < sourcecount; i++) ret += (source.get(i) - sourceAvg) * (other.get(i) - targetAvg); return ret / (sourcecount - 1); } pearson(other, selector, predicate) { const source = this.where(predicate).select(selector); const target = other.where(predicate).select(selector); return source.covariance(target) / (source.stdDevP() * other.stdDevP()); } varianceP(selector, predicate) { const source = this.where(predicate).select(selector); const count = source.count(); if (count === 0) return 0; const mean = source.average(); const squareDiffs = source.select(item => { const d = item; return (d - mean) * (d - mean); }); const ret = squareDiffs.sum() / (count - 1); return ret; } percentile(percentile, selector, predicate) { return this.percentileInclusive(percentile, selector, predicate); } percentileInclusive(percentile, selector, predicate) { const source = this.where(predicate) .select(selector) .orderBy(key => key); const length = source.count(); const index = percentile * (length - 1); const integerComponentOfIndex = Math.floor(index); const decimalComponentOfIndex = index - integerComponentOfIndex; const keyAtIndex = source.get(integerComponentOfIndex); if (integerComponentOfIndex >= length - 1) { return keyAtIndex; } const keyAtNextIndex = source.get(integerComponentOfIndex); return keyAtIndex + (keyAtNextIndex - keyAtIndex) * decimalComponentOfIndex; } percentileExclusive(percentile, selector, predicate) { const source = this.where(predicate) .select(selector) .orderBy(key => key); const length = source.count(); const index = percentile * (length + 1) - 1; const integerComponentOfIndex = Math.floor(index); const decimalComponentOfIndex = index - integerComponentOfIndex; const keyAtIndex = source.get(integerComponentOfIndex); const keyAtNextIndex = source.get(integerComponentOfIndex); return keyAtIndex + (keyAtNextIndex - keyAtIndex) * decimalComponentOfIndex; } percentRank(value, selector, predicate) { selector = selector || ((xx) => xx); const source = this.where(predicate).orderBy(selector); const array = source.toArray(); let L = 0; let S = 0; const N = array.length; for (let i = 0; i < array.length; i++) { if (array[i] < value) { L += 1; } else if (array[i] === value) { S += 1; } } const pct = (L + 0.5 * S) / N; return pct; } mean(selector, predicate) { selector = selector || ((xx) => xx); return this.average(selector, predicate); } median(selector, predicate) { selector = selector || ((xx) => xx); const source = this.where(predicate).orderBy(selector); const count = source.count(); const mindex = Math.floor(count / 2); if (count % 2 === 0) { return (((selector ? selector(source.get(mindex)) : source.get(mindex)) + (selector ? selector(source.get(mindex - 1)) : source.get(mindex - 1))) / 2); } return selector ? selector(source.get(mindex)) : source.get(mindex); } mode(selector, predicate) { selector = selector || ((xx) => xx); const source = this.where(predicate).select(selector); const array = source.toArray(); let hasDuplicate = false; if (array.length < 2) return Number.NaN; let maxValue = Number.MIN_VALUE, maxCount = 0; for (let i = 0; i < array.length; ++i) { let count = 0; if (!hasDuplicate && array.lastIndexOf(array[i]) !== i) { hasDuplicate = true; } for (let j = 0; j < array.length; ++j) { if (array[j] === array[i]) ++count; } if (count > maxCount) { maxCount = count; maxValue = array[i]; } } if (!hasDuplicate) return Number.NaN; return maxValue === Number.MIN_VALUE ? Number.NaN : maxValue; } range(selector, predicate) { selector = selector || ((xx) => xx); const source = this.where(predicate).select(selector); const ret = source.max() - source.min(); return ret; } get(index) { const enb = this[Symbol.iterator](); for (let i = 0; i <= index; i++) { const next = enb.next(); if (i === index) return next.value; } return null; } forEach(action) { let i = 0; for (const x of this) { action(x, i++); } } toArray() { const aa = []; for (const x of this) { aa.push(x); } return aa; } toList() { const xx = new List_1.List(); for (const x of this) { xx.add(x); } return xx; } toCollection() { const xx = new Collection_1.Collection(); for (const x of this) { xx.add(x); } return xx; } intersect(source, equalityComparator) { equalityComparator = equalityComparator || Enumerable.equalityComparator; const wset = new Set(); for (const xx of source) { if (this.contains(xx)) { wset.add(xx); } } return new Enumerable(wset); } subtract(source, equalityComparator) { equalityComparator = equalityComparator || Enumerable.equalityComparator; const wset = new Set(); const inter = this.intersect(source); for (const xx of this) { if (!inter.contains(xx)) { wset.add(xx); } } return new Enumerable(wset); } union(source, equalityComparator) { equalityComparator = equalityComparator || Enumerable.equalityComparator; const wset = new Set(); for (const xx of this) { wset.add(xx); } for (const xx of source) { if (!wset.has(xx)) { wset.add(xx); } } return new Enumerable(wset); } zip(second, selector) { const thisme = this; const enb1 = thisme.enumerable[Symbol.iterator](); const enb2 = new Enumerable(second)[Symbol.iterator](); const itr = { [Symbol.iterator]: () => { return { next: () => { const item1 = enb1.next(); const item2 = enb2.next(); if (item1.done === false && item2.done === false) { return { value: selector(item1.value, item2.value), done: false }; } else { return { done: true }; } }, }; }, }; return new Enumerable(itr); } [Symbol.iterator]() { if (this.enumerable && this.enumerable[Symbol.iterator]) { return this.enumerable[Symbol.iterator](); } throw new index_1.IllegalOperationException(-250, 'The object is not itrabe .'); } } exports.Enumerable = Enumerable; class OrderedEnumerable extends Enumerable { constructor(enumerable, options) { super(enumerable, options); } thenBy(selector, comparator) { comparator = comparator || Enumerable.comparator; const cmp = (a, b) => { return comparator(selector(a), selector(b)); }; return this.orderBy(Enumerable.selector, (a, b) => { const res = cmp(a, b); return res === 0 ? comparator(selector(a), selector(b)) : res; }); } thenByDesc(selector, comparator) { comparator = comparator || Enumerable.comparator; const cmp = (a, b) => { return comparator(selector(a), selector(b)); }; return this.orderBy(Enumerable.selector, (a, b) => { const res = cmp(a, b); return res === 0 ? -comparator(selector(a), selector(b)) : res; }); } } exports.OrderedEnumerable = OrderedEnumerable;