linq-extensions
Version:
Linq-like extension methods for JavaScript and TypeScript builtin collections
371 lines • 14.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.range = exports.random = exports.generate = exports.from = exports.empty = void 0;
const iterable_1 = require("./iterable");
const where_iterable_1 = require("./iterables/where-iterable");
const apped_iterable_1 = require("./iterables/apped-iterable");
const distinct_iterable_1 = require("./iterables/distinct-iterable");
const range_iterable_1 = require("./iterables/range-iterable");
const empty_iterable_1 = require("./iterables/empty-iterable");
const select_iterable_1 = require("./iterables/select-iterable");
const grouping_iterable_1 = require("./iterables/grouping-iterable");
const inner_join_iterable_1 = require("./iterables/join/inner-join-iterable");
const types_1 = require("./types");
const left_join_iterable_1 = require("./iterables/join/left-join-iterable");
const ordered_iterable_1 = require("./iterables/ordered-iterable");
const ordering_1 = require("./iterables/ordering/ordering");
const outer_join_iterable_1 = require("./iterables/join/outer-join-iterable");
const reverse_iterable_1 = require("./iterables/reverse-iterable");
const select_many_iterable_1 = require("./iterables/select-many-iterable");
const skip_while_iterable_1 = require("./iterables/skip-while-iterable");
const take_while_iterable_1 = require("./iterables/take-while-iterable");
const batch_iterable_1 = require("./iterables/batch-iterable");
const insert_iterable_1 = require("./iterables/insert-iterable");
iterable_1.Iterable.prototype.aggregate = function (seed, accumulator) {
let accumulate = seed;
for (const element of this) {
accumulate = accumulator(accumulate, element);
}
return accumulate;
};
iterable_1.Iterable.prototype.all = function (predicate) {
for (const element of this) {
if (!predicate(element)) {
return false;
}
}
return true;
};
iterable_1.Iterable.prototype.any = function (predicate) {
return !this.all(element => !predicate(element));
};
iterable_1.Iterable.prototype.append = function (element) {
return this.appendMany([element]);
};
iterable_1.Iterable.prototype.appendMany = function (elements) {
return new apped_iterable_1.AppendIterable(this, elements);
};
iterable_1.Iterable.prototype.asIterable = function () {
return this;
};
iterable_1.Iterable.prototype.atLeast = function (count, predicate = element => true) {
if (count < 0) {
throw new Error('The count must be a non-negative number.');
}
let matches = 0;
for (const element of this) {
if (predicate(element)) {
matches++;
}
if (matches >= count) {
return true;
}
}
return false;
};
iterable_1.Iterable.prototype.atMost = function (count, predicate = element => true) {
let matches = 0;
for (const element of this) {
if (predicate(element)) {
matches++;
}
if (matches > count) {
return false;
}
}
return true;
};
iterable_1.Iterable.prototype.average = function () {
let sum = 0;
let count = 0;
for (const element of this) {
if (typeof element !== 'number') {
throw new Error('Average can only be calculated on sequences that only contain numbers.');
}
sum += element;
count++;
}
return sum / count;
};
iterable_1.Iterable.prototype.averageOf = function (selector) {
return this.select(selector).average();
};
iterable_1.Iterable.prototype.backwards = function () {
return new reverse_iterable_1.ReverseIterable(this);
};
iterable_1.Iterable.prototype.batch = function (batchSize) {
if (batchSize < 1) {
throw new Error('The batch size must be a positive number.');
}
return new batch_iterable_1.BatchIterable(this, batchSize);
};
iterable_1.Iterable.prototype.count = function (predicate = element => true) {
let count = 0;
for (const element of this) {
if (predicate(element)) {
count++;
}
}
return count;
};
iterable_1.Iterable.prototype.distinct = function (equalityCheck) {
return this.distinctBy(x => x, equalityCheck);
};
iterable_1.Iterable.prototype.distinctBy = function (selector, equalityCheck = types_1.defaultEqualityCheck) {
return new distinct_iterable_1.DistinctIterable(this, selector, equalityCheck);
};
iterable_1.Iterable.prototype.elementAt = function (index) {
if (index < 0) {
throw new Error('Index out of range.');
}
let i = 0;
for (const element of this) {
if (i === index) {
return element;
}
i++;
}
throw new Error('Index out of range.');
};
iterable_1.Iterable.prototype.endsWith = function (otherIterable, equalityCheck = types_1.defaultEqualityCheck) {
const iterators = [];
for (const element of this) {
for (let i = iterators.length - 1; i >= 0; i--) {
const result = iterators[i].next();
if (result.done || !equalityCheck(result.value, element)) {
iterators.splice(i, 1);
}
}
const newIterator = otherIterable[Symbol.iterator]();
const result = newIterator.next();
if (result.value === element) {
iterators.push(newIterator);
}
}
return iterators.any(x => !!x.next().done);
};
iterable_1.Iterable.prototype.exactly = function (count, predicate = () => true) {
return this.count(predicate) === count;
};
iterable_1.Iterable.prototype.first = function (predicate) {
const firstOrNull = this.firstOrNull(predicate);
if (firstOrNull !== null) {
return firstOrNull;
}
else {
throw new Error('The sequence contains no matching element.');
}
};
iterable_1.Iterable.prototype.firstOrNull = function (predicate = element => true) {
for (const element of this) {
if (predicate(element)) {
return element;
}
}
return null;
};
iterable_1.Iterable.prototype.groupBy = function (keySelector, equalityCheck = types_1.defaultEqualityCheck) {
return new grouping_iterable_1.GroupingIterable(this, keySelector, equalityCheck);
};
iterable_1.Iterable.prototype.innerJoin = function (otherIterable, condition, selector) {
return new inner_join_iterable_1.InnerJoinIterable(this, otherIterable, condition, selector);
};
iterable_1.Iterable.prototype.insert = function (index, element) {
return this.insertMany(index, [element]);
};
iterable_1.Iterable.prototype.insertMany = function (index, elements) {
return new insert_iterable_1.InsertIterable(this, index, elements);
};
iterable_1.Iterable.prototype.intersect = function (otherIterable, equalityCheck = types_1.defaultEqualityCheck) {
return this.innerJoin(otherIterable, equalityCheck, (left, right) => left).distinct(equalityCheck);
};
iterable_1.Iterable.prototype.last = function (predicate) {
const lastOrNull = this.lastOrNull(predicate);
if (lastOrNull === null) {
throw new Error('The sequence contains no matching element.');
}
return lastOrNull;
};
iterable_1.Iterable.prototype.lastOrNull = function (predicate = element => true) {
let last = null;
for (const element of this) {
if (predicate(element)) {
last = element;
}
}
return last;
};
iterable_1.Iterable.prototype.leftJoin = function (otherIterable, condition, selector) {
return new left_join_iterable_1.LeftJoinIterable(this, otherIterable, condition, selector);
};
iterable_1.Iterable.prototype.max = function (comparator = types_1.defaultComparator) {
let max = null;
for (const element of this) {
if (max === null || comparator(max, element) < 0) {
max = element;
}
}
if (max === null) {
throw new Error('The sequence contains no elements.');
}
return max;
};
iterable_1.Iterable.prototype.maxBy = function (selector, comparator = types_1.defaultComparator) {
return this.select(x => ({ original: x, selected: selector(x) }))
.max((left, right) => comparator(left.selected, right.selected)).original;
};
iterable_1.Iterable.prototype.maxOf = function (selector, comparator) {
return this.select(selector).max(comparator);
};
iterable_1.Iterable.prototype.min = function (comparator = types_1.defaultComparator) {
return this.max((left, right) => comparator(right, left));
};
iterable_1.Iterable.prototype.minBy = function (selector, comparator = types_1.defaultComparator) {
return this.maxBy(selector, (left, right) => comparator(right, left));
};
iterable_1.Iterable.prototype.maxOf = function (selector, comparator = types_1.defaultComparator) {
return this.maxOf(selector, (left, right) => comparator(right, left));
};
iterable_1.Iterable.prototype.orderBy = function (selector, comparator = types_1.defaultComparator) {
return new ordered_iterable_1.OrderedIterable(this, new ordering_1.Ordering(selector, comparator, 'asc'));
};
iterable_1.Iterable.prototype.orderByDescending = function (selector, comparator = types_1.defaultComparator) {
return new ordered_iterable_1.OrderedIterable(this, new ordering_1.Ordering(selector, comparator, 'desc'));
};
iterable_1.Iterable.prototype.outerJoin = function (otherIterable, condition, selector) {
return new outer_join_iterable_1.OuterJoinIterable(this, otherIterable, condition, selector);
};
iterable_1.Iterable.prototype.prepend = function (element) {
return this.prependMany([element]);
};
iterable_1.Iterable.prototype.prependMany = function (otherIterable) {
return otherIterable.appendMany(this);
};
iterable_1.Iterable.prototype.rightJoin = function (otherIterable, condition, selector) {
return otherIterable.leftJoin(this, (left, right) => condition(right, left), (left, right) => selector(right, left));
};
iterable_1.Iterable.prototype.select = function (selector) {
return new select_iterable_1.SelectIterable(this, selector);
};
iterable_1.Iterable.prototype.selectMany = function (collectionSelector, selector = (left, right) => right) {
return new select_many_iterable_1.SelectManyIterable(this, collectionSelector, selector);
};
iterable_1.Iterable.prototype.sequenceEqual = function (otherIterable, equalityCheck = types_1.defaultEqualityCheck) {
const iterator1 = this[Symbol.iterator]();
const iterator2 = otherIterable[Symbol.iterator]();
while (true) {
const result1 = iterator1.next();
const result2 = iterator2.next();
if (result1.done) {
if (result2.done) {
return true;
}
else {
return false;
}
}
else {
if (result2.done) {
return false;
}
else {
if (!equalityCheck(result1.value, result2.value)) {
return false;
}
}
}
}
};
iterable_1.Iterable.prototype.single = function (predicate) {
const singleOrNull = this.singleOrNull();
if (singleOrNull === null) {
throw new Error('The sequence contains no matching element.');
}
return singleOrNull;
};
iterable_1.Iterable.prototype.skip = function (count) {
return this.skipWhile((element, index) => index < count);
};
iterable_1.Iterable.prototype.skipLast = function (count) {
const iterableCount = this.count();
return this.takeWhile((element, index) => index < iterableCount - count);
};
iterable_1.Iterable.prototype.skipWhile = function (predicate) {
return new skip_while_iterable_1.SkipWhileIterable(this, predicate);
};
iterable_1.Iterable.prototype.sum = function () {
let sum = 0;
for (const element of this) {
if (typeof element !== 'number') {
throw new Error('Sum can only be calculated on sequences that only contain numbers.');
}
sum += element;
}
return sum;
};
iterable_1.Iterable.prototype.sumOf = function (selector) {
return this.select(selector).sum();
};
iterable_1.Iterable.prototype.take = function (count) {
return this.takeWhile((element, index) => index < count);
};
iterable_1.Iterable.prototype.takeLast = function (count) {
const iterableCount = this.count();
return this.skipWhile((element, index) => index < iterableCount - count);
};
iterable_1.Iterable.prototype.takeWhile = function (predicate) {
return new take_while_iterable_1.TakeWhileIterable(this, predicate);
};
iterable_1.Iterable.prototype.singleOrNull = function (predicate) {
let result = null;
for (const element of this) {
if (predicate(element)) {
if (result) {
throw new Error('The sequence contains more than one matching element.');
}
else {
result = element;
}
}
}
return result;
};
iterable_1.Iterable.prototype.toArray = function () {
return Array.from(this);
};
iterable_1.Iterable.prototype.toMap = function (keySelector, valueSelector) {
return new Map(this.select(x => [keySelector(x), valueSelector(x)]));
};
iterable_1.Iterable.prototype.toSet = function () {
return new Set(this);
};
iterable_1.Iterable.prototype.union = function (otherIterable, equalityCheck) {
return this.appendMany(otherIterable).distinct(equalityCheck);
};
iterable_1.Iterable.prototype.where = function (predicate) {
return new where_iterable_1.WhereIterable(this, predicate);
};
Object.assign(Array.prototype, iterable_1.Iterable.prototype);
Object.assign(Set.prototype, iterable_1.Iterable.prototype);
Object.assign(Map.prototype, iterable_1.Iterable.prototype);
function empty() {
return new empty_iterable_1.EmptyIterable();
}
exports.empty = empty;
function from(...elements) {
return elements;
}
exports.from = from;
function generate(count, generator) {
return range(0, count).select(generator);
}
exports.generate = generate;
function random(count, minimum, maximum) {
return range(0, count).select(() => Math.random() * maximum + minimum);
}
exports.random = random;
function range(from, count) {
return new range_iterable_1.RangeIterable(from, count);
}
exports.range = range;
//# sourceMappingURL=linq.js.map