UNPKG

@adamburgess/linq

Version:
279 lines (278 loc) 7.33 kB
import { byMin_byMax_min_max, concat, createLazyGenerator, distinct, flat, groupBy, groupByMap, map, reverse, skip, skipWhile, take, takeWhile, where } from "./enumerable.js"; class SequenceKlass { constructor(it) { this.it = it; } map(f) { return new SequenceKlass(map(this, f)); } where(f) { return new SequenceKlass(where(this, f)); } reverse() { return new SequenceKlass(reverse(this)); } groupBy(keySelector, elementSelector) { return new SequenceKlass(groupBy(this, keySelector, elementSelector)).map((kv) => new KeySequenceKlass(kv[1], kv[0])); } orderBy(selector, comparer) { return new OrderedSequenceKlass(this, [{ selector, comparer: comparer || defaultComparer, ascending: true }]); } orderByDescending(selector, comparer) { return new OrderedSequenceKlass(this, [{ selector, comparer: comparer || defaultComparer, ascending: false }]); } take(count) { return new SequenceKlass(take(this, count)); } takeWhile(predicate) { return new SequenceKlass(takeWhile(this, predicate)); } skip(count) { return new SequenceKlass(skip(this, count)); } skipWhile(predicate) { return new SequenceKlass(skipWhile(this, predicate)); } append(iterable) { return new SequenceKlass(concat(this, iterable)); } prepend(iterable) { return new SequenceKlass(concat(iterable, this)); } distinct(keySelector) { return new SequenceKlass(distinct(this, keySelector)); } flat(projector) { return new SequenceKlass(flat(projector ? this.map(projector) : this)); } join(innerSequence, outerKeySelector, innerKeySelector, resultSelector) { const distinctInner = from(innerSequence).toMap(innerKeySelector, (x) => x); const that = this; return new SequenceKlass(createLazyGenerator(function* join() { for (const outerValue of that) { const key = outerKeySelector(outerValue); const innerValue = distinctInner.get(key); if (innerValue) { yield resultSelector(outerValue, innerValue); } } })); } groupJoin(innerSequence, outerKeySelector, innerKeySelector, resultSelector) { const that = this; return new SequenceKlass(createLazyGenerator(function* groupJoin() { const groupedInner = groupByMap(innerSequence, innerKeySelector); for (const outerValue of that) { const key = outerKeySelector(outerValue); const innerValue = groupedInner.get(key); if (innerValue) { yield resultSelector(outerValue, from(innerValue)); } } })); } count() { let count = 0; for (const _ of this) count++; return count; } sum(f) { let value = 0; for (const x of this) { value += f ? f(x) : x; } return value; } average(f) { let value = 0; let count = 0; for (const x of this) { value += f ? f(x) : x; count++; } if (count === 0) throw new Error("empty"); return value / count; } min(f) { return byMin_byMax_min_max(this, f, true, false); } max(f) { return byMin_byMax_min_max(this, f, false, false); } minBy(f) { return byMin_byMax_min_max(this, f, true, true); } maxBy(f) { return byMin_byMax_min_max(this, f, false, true); } all(predicate) { for (const x of this) { if (!predicate(x)) return false; } return true; } any(predicate) { for (const x of this) { if (predicate ? predicate(x) : true) return true; } return false; } none(predicate) { return !this.any(predicate); } contains(value) { return this.any((x) => x === value); } toArray() { return Array.from(this); } toMap(keySelector, elementSelector) { const map2 = /* @__PURE__ */ new Map(); for (const e of this) { const key = keySelector(e); if (!map2.has(key)) map2.set(key, elementSelector(e)); } return map2; } toObject(keySelector, elementSelector) { const record = {}; const keys = /* @__PURE__ */ new Set(); for (const x of this) { const key = keySelector(x); if (!keys.has(key)) { record[key] = elementSelector(x); keys.add(key); } } return record; } toSet(projector) { return projector ? new Set(this.map(projector)) : new Set(this); } first(predicate) { if (predicate) return this.where(predicate).first(); const iterator = this[Symbol.iterator](); const result = iterator.next(); if (result.done) throw new Error("empty"); return result.value; } firstOrDefault(predicate) { if (predicate) return this.where(predicate).firstOrDefault(); const iterator = this[Symbol.iterator](); const result = iterator.next(); return result.value; } single(predicate) { if (predicate) return this.where(predicate).single(); const iterator = this[Symbol.iterator](); const result1 = iterator.next(); if (result1.done) throw new Error("empty"); const result2 = iterator.next(); if (!result2.done) throw new Error("more than 1"); return result1.value; } singleOrDefault(predicate) { if (predicate) return this.where(predicate).singleOrDefault(); const iterator = this[Symbol.iterator](); const result1 = iterator.next(); if (result1.done) return void 0; const result2 = iterator.next(); if (!result2.done) return void 0; return result1.value; } last(predicate) { if (predicate) return this.where(predicate).last(); let stored = void 0; for (const x of this) { stored = x; } if (stored === void 0) throw new Error("empty"); return stored; } lastOrDefault(predicate) { if (predicate) return this.where(predicate).lastOrDefault(); let stored = void 0; for (const x of this) { stored = x; } return stored; } joinString(separator) { return this.toArray().join(separator); } [Symbol.iterator]() { return this.it[Symbol.iterator](); } } class KeySequenceKlass extends SequenceKlass { constructor(it, key) { super(it); this.key = key; } } const defaultComparer = (a, b) => a > b ? 1 : a < b ? -1 : 0; class OrderedSequenceKlass extends SequenceKlass { constructor(it, sc) { super(it); this.sc = sc; } thenBy(selector, comparer) { return new OrderedSequenceKlass(this.it, [...this.sc, { selector, comparer: comparer || defaultComparer, ascending: true }]); } thenByDescending(selector, comparer) { return new OrderedSequenceKlass(this.it, [...this.sc, { selector, comparer: comparer || defaultComparer, ascending: false }]); } [Symbol.iterator]() { const elements = Array.from(this.it); elements.sort((a, b) => { for (const compare of this.sc) { let result = compare.comparer(compare.selector(a), compare.selector(b)); if (!compare.ascending) result = -result; if (result !== 0) return result; } return 0; }); return elements[Symbol.iterator](); } } export function from(it) { if (it instanceof SequenceKlass) return it; return new SequenceKlass(it); } export default from;