@softwareventures/array
Version:
Pure functional array manipulation and traversal
1,206 lines • 37.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.map = exports.isArray = exports.copy = void 0;
exports.isArrayLike = isArrayLike;
exports.coerce = coerce;
exports.first = first;
exports.tail = tail;
exports.push = push;
exports.pushFn = pushFn;
exports.unshift = unshift;
exports.unshiftFn = unshiftFn;
exports.initial = initial;
exports.last = last;
exports.only = only;
exports.empty = empty;
exports.notEmpty = notEmpty;
exports.reverse = reverse;
exports.slice = slice;
exports.sliceFn = sliceFn;
exports.take = take;
exports.takeFn = takeFn;
exports.drop = drop;
exports.dropFn = dropFn;
exports.takeWhile = takeWhile;
exports.takeWhileFn = takeWhileFn;
exports.takeUntil = takeUntil;
exports.takeUntilFn = takeUntilFn;
exports.dropWhile = dropWhile;
exports.dropWhileFn = dropWhileFn;
exports.dropUntil = dropUntil;
exports.dropUntilFn = dropUntilFn;
exports.equal = equal;
exports.equalFn = equalFn;
exports.notEqual = notEqual;
exports.notEqualFn = notEqualFn;
exports.prefixMatch = prefixMatch;
exports.prefixMatchFn = prefixMatchFn;
exports.mapFn = mapFn;
exports.filter = filter;
exports.filterFn = filterFn;
exports.exclude = exclude;
exports.excludeFn = excludeFn;
exports.excludeNull = excludeNull;
exports.excludeFirst = excludeFirst;
exports.excludeFirstFn = excludeFirstFn;
exports.remove = remove;
exports.removeFn = removeFn;
exports.removeFirst = removeFirst;
exports.removeFirstFn = removeFirstFn;
exports.fold = fold;
exports.foldFn = foldFn;
exports.fold1 = fold1;
exports.fold1Fn = fold1Fn;
exports.foldRight = foldRight;
exports.foldRightFn = foldRightFn;
exports.foldRight1 = foldRight1;
exports.foldRight1Fn = foldRight1Fn;
exports.foldMap = foldMap;
exports.foldMapFn = foldMapFn;
exports.foldMapRight = foldMapRight;
exports.foldMapRightFn = foldMapRightFn;
exports.contains = contains;
exports.containsFn = containsFn;
exports.indexOf = indexOf;
exports.indexOfFn = indexOfFn;
exports.lastIndexOf = lastIndexOf;
exports.lastIndexOfFn = lastIndexOfFn;
exports.findIndex = findIndex;
exports.findIndexFn = findIndexFn;
exports.findLastIndex = findLastIndex;
exports.findLastIndexFn = findLastIndexFn;
exports.find = find;
exports.findFn = findFn;
exports.findLast = findLast;
exports.findLastFn = findLastFn;
exports.maximum = maximum;
exports.maximumFn = maximumFn;
exports.maximumBy = maximumBy;
exports.maximumByFn = maximumByFn;
exports.minimum = minimum;
exports.minimumFn = minimumFn;
exports.minimumBy = minimumBy;
exports.minimumByFn = minimumByFn;
exports.sum = sum;
exports.product = product;
exports.average = average;
exports.and = and;
exports.or = or;
exports.any = any;
exports.anyFn = anyFn;
exports.all = all;
exports.allFn = allFn;
exports.concat = concat;
exports.prepend = prepend;
exports.append = append;
exports.concatMap = concatMap;
exports.concatMapFn = concatMapFn;
exports.noneNull = noneNull;
exports.scan = scan;
exports.scanFn = scanFn;
exports.scan1 = scan1;
exports.scan1Fn = scan1Fn;
exports.scanRight = scanRight;
exports.scanRightFn = scanRightFn;
exports.scanRight1 = scanRight1;
exports.scanRight1Fn = scanRight1Fn;
exports.split = split;
exports.splitFn = splitFn;
exports.partition = partition;
exports.partitionFn = partitionFn;
exports.partitionWhile = partitionWhile;
exports.partitionWhileFn = partitionWhileFn;
exports.partitionUntil = partitionUntil;
exports.partitionUntilFn = partitionUntilFn;
exports.zip = zip;
exports.zipFn = zipFn;
exports.keyBy = keyBy;
exports.keyByFn = keyByFn;
exports.keyFirstBy = keyFirstBy;
exports.keyFirstByFn = keyFirstByFn;
exports.keyLastBy = keyLastBy;
exports.keyLastByFn = keyLastByFn;
exports.mapKeyBy = mapKeyBy;
exports.mapKeyByFn = mapKeyByFn;
exports.mapKeyFirstBy = mapKeyFirstBy;
exports.mapKeyFirstByFn = mapKeyFirstByFn;
exports.mapKeyLastBy = mapKeyLastBy;
exports.mapKeyLastByFn = mapKeyLastByFn;
exports.group = group;
exports.groupFn = groupFn;
exports.groupByIdentity = groupByIdentity;
exports.groupByIdentityFn = groupByIdentityFn;
exports.groupByEquality = groupByEquality;
exports.groupByEqualityFn = groupByEqualityFn;
exports.groupByOrder = groupByOrder;
exports.groupByOrderFn = groupByOrderFn;
exports.groupByHash = groupByHash;
exports.groupByHashFn = groupByHashFn;
exports.groupByEqualityWithHash = groupByEqualityWithHash;
exports.groupByEqualityWithHashFn = groupByEqualityWithHashFn;
exports.groupByOrderWithHash = groupByOrderWithHash;
exports.groupByOrderWithHashFn = groupByOrderWithHashFn;
exports.groupAdjacent = groupAdjacent;
exports.groupAdjacentFn = groupAdjacentFn;
exports.groupAdjacentByIdentity = groupAdjacentByIdentity;
exports.groupAdjacentByIdentityFn = groupAdjacentByIdentityFn;
exports.groupAdjacentByEquality = groupAdjacentByEquality;
exports.groupAdjacentByEqualityFn = groupAdjacentByEqualityFn;
exports.groupAdjacentByOrder = groupAdjacentByOrder;
exports.groupAdjacentByOrderFn = groupAdjacentByOrderFn;
exports.groupAdjacentByHash = groupAdjacentByHash;
exports.groupAdjacentByHashFn = groupAdjacentByHashFn;
exports.unique = unique;
exports.uniqueFn = uniqueFn;
exports.uniqueByIdentity = uniqueByIdentity;
exports.uniqueByEquality = uniqueByEquality;
exports.uniqueByEqualityFn = uniqueByEqualityFn;
exports.uniqueByOrder = uniqueByOrder;
exports.uniqueByOrderFn = uniqueByOrderFn;
exports.uniqueByHash = uniqueByHash;
exports.uniqueByHashFn = uniqueByHashFn;
exports.uniqueByEqualityWithHash = uniqueByEqualityWithHash;
exports.uniqueByEqualityWithHashFn = uniqueByEqualityWithHashFn;
exports.uniqueByOrderWithHash = uniqueByOrderWithHash;
exports.uniqueByOrderWithHashFn = uniqueByOrderWithHashFn;
exports.uniqueAdjacent = uniqueAdjacent;
exports.uniqueAdjacentFn = uniqueAdjacentFn;
exports.uniqueAdjacentByIdentity = uniqueAdjacentByIdentity;
exports.uniqueAdjacentByIdentityFn = uniqueAdjacentByIdentityFn;
exports.uniqueAdjacentByEquality = uniqueAdjacentByEquality;
exports.uniqueAdjacentByEqualityFn = uniqueAdjacentByEqualityFn;
exports.uniqueAdjacentByOrder = uniqueAdjacentByOrder;
exports.uniqueAdjacentByOrderFn = uniqueAdjacentByOrderFn;
exports.uniqueAdjacentByHash = uniqueAdjacentByHash;
exports.uniqueAdjacentByHashFn = uniqueAdjacentByHashFn;
exports.sort = sort;
exports.sortFn = sortFn;
exports.sortBy = sortBy;
exports.sortByFn = sortByFn;
exports.sortByDescending = sortByDescending;
exports.sortByDescendingFn = sortByDescendingFn;
exports.forEach = forEach;
exports.forEachFn = forEachFn;
const nullable_1 = require("@softwareventures/nullable");
const ordered_1 = require("@softwareventures/ordered");
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeSlice = Array.prototype.slice;
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeReverse = Array.prototype.reverse;
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeConcat = Array.prototype.concat;
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeFilter = Array.prototype.filter;
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeReduce = Array.prototype.reduce;
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeReduceRight = Array.prototype.reduceRight;
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeIndexOf = Array.prototype.indexOf;
// eslint-disable-next-line @typescript-eslint/unbound-method
const nativeFindIndex = Array.prototype.findIndex;
/** @internal This implementation is for internal use only, the exported declaration is above */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore duplicate identifier: This is the actual implementation, the exported declaration is above.
exports.copy = Array.from;
/** @internal This implementation is for internal use only, the exported declaration is above */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore duplicate identifier: This is the actual implementation, the exported declaration is above.
exports.isArray = Array.isArray;
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
function isArrayLike(value) {
return (typeof value === "object" &&
value != null &&
"length" in value &&
typeof value.length === "number");
}
function coerce(array) {
return (0, exports.isArray)(array) ? array : (0, exports.copy)(array);
}
function first(array) {
return array.length === 0 ? null : array[0];
}
function tail(array) {
return nativeSlice.call(array, 1);
}
function push(array, value) {
return [...coerce(array), value];
}
function pushFn(value) {
return array => push(array, value);
}
function unshift(array, value) {
return [value, ...coerce(array)];
}
function unshiftFn(value) {
return array => unshift(array, value);
}
function initial(array) {
return array.length === 0 ? [] : nativeSlice.call(array, 0, array.length - 1);
}
function last(array) {
return array.length === 0 ? null : array[array.length - 1];
}
/** If the array contains exactly one element, returns that element.
* Otherwise, returns null. */
function only(array) {
return array.length === 1 ? array[0] : null;
}
function empty(array) {
return array.length === 0;
}
function notEmpty(array) {
return array.length > 0;
}
function reverse(array) {
return nativeReverse.call((0, exports.copy)(array));
}
function slice(array, start, end) {
return nativeSlice.call(array, start, end);
}
function sliceFn(start, end) {
return array => nativeSlice.call(array, start, end);
}
function take(array, count) {
return nativeSlice.call(array, 0, count);
}
function takeFn(count) {
return array => nativeSlice.call(array, 0, count);
}
function drop(array, count) {
return nativeSlice.call(array, count);
}
function dropFn(count) {
return array => nativeSlice.call(array, count);
}
function takeWhile(array, predicate) {
let i = 0;
while (i < array.length && predicate(array[i], i)) {
++i;
}
return take(array, i);
}
function takeWhileFn(predicate) {
return array => takeWhile(array, predicate);
}
function takeUntil(array, predicate) {
return takeWhile(array, (element, index) => !predicate(element, index));
}
function takeUntilFn(predicate) {
return array => takeUntil(array, predicate);
}
function dropWhile(array, predicate) {
let i = 0;
while (i < array.length && predicate(array[i], i)) {
++i;
}
return drop(array, i);
}
function dropWhileFn(predicate) {
return array => dropWhile(array, predicate);
}
function dropUntil(array, predicate) {
return dropWhile(array, (element, index) => !predicate(element, index));
}
function dropUntilFn(predicate) {
return array => dropWhile(array, predicate);
}
function equal(a, b, elementsEqual = ordered_1.equal) {
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; ++i) {
if (!elementsEqual(a[i], b[i])) {
return false;
}
}
return true;
}
function equalFn(b, elementsEqual = ordered_1.equal) {
return a => equal(a, b, elementsEqual);
}
function notEqual(a, b, elementsEqual = ordered_1.equal) {
return !equal(a, b, elementsEqual);
}
function notEqualFn(b, elementsEqual = ordered_1.equal) {
return a => notEqual(a, b, elementsEqual);
}
function prefixMatch(a, b, elementsEqual = ordered_1.equal) {
if (a.length < b.length) {
return false;
}
for (let i = 0; i < b.length; ++i) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function prefixMatchFn(b, elementsEqual = ordered_1.equal) {
return a => prefixMatch(a, b, elementsEqual);
}
/** @internal This implementation is for internal use only, the exported declaration is above */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore duplicate identifier: This is the actual implementation, the exported declaration is above.
exports.map = Array.from;
function mapFn(f) {
return array => Array.from(array, f);
}
function filter(array, predicate) {
return nativeFilter.call(array, predicate);
}
function filterFn(predicate) {
return array => nativeFilter.call(array, predicate);
}
function exclude(array, predicate) {
return filter(array, (element, index) => !predicate(element, index));
}
function excludeFn(predicate) {
return array => exclude(array, predicate);
}
function excludeNull(array) {
return filter(array, nullable_1.isNotNull);
}
function excludeFirst(array, predicate) {
const result = [];
let i = 0;
for (; i < array.length; ++i) {
const element = array[i];
if (!predicate(element, i)) {
result.push(element);
}
else {
break;
}
}
for (++i; i < array.length; ++i) {
result.push(array[i]);
}
return result;
}
function excludeFirstFn(predicate) {
return array => excludeFirst(array, predicate);
}
function remove(array, value) {
return exclude(array, element => element === value);
}
function removeFn(value) {
return array => remove(array, value);
}
function removeFirst(array, value) {
return excludeFirst(array, element => element === value);
}
function removeFirstFn(value) {
return array => removeFirst(array, value);
}
function fold(array, f, initial) {
return nativeReduce.call(array, f, initial);
}
function foldFn(f, initial) {
return array => nativeReduce.call(array, f, initial);
}
function fold1(array, f) {
return nativeReduce.call(array, f);
}
function fold1Fn(f) {
return array => fold1(array, f);
}
function foldRight(array, f, initial) {
return nativeReduceRight.call(array, f, initial);
}
function foldRightFn(f, initial) {
return array => nativeReduceRight.call(array, f, initial);
}
function foldRight1(array, f) {
return nativeReduceRight.call(array, f);
}
function foldRight1Fn(f) {
return array => foldRight1(array, f);
}
function foldMap(array, f, m, initial) {
let accumulator = initial;
for (let i = 0; i < array.length; ++i) {
accumulator = f(accumulator, m(array[i], i), i);
}
return accumulator;
}
function foldMapFn(f, m, initial) {
return array => foldMap(array, f, m, initial);
}
function foldMapRight(array, f, m, initial) {
let accumulator = initial;
const length = array.length;
for (let i = 0; i < array.length; ++i) {
accumulator = f(accumulator, m(array[length - i], i), i);
}
return accumulator;
}
function foldMapRightFn(f, m, initial) {
return array => foldMapRight(array, f, m, initial);
}
function contains(array, value) {
return nativeIndexOf.call(array, value) !== -1;
}
function containsFn(value) {
return array => nativeIndexOf.call(array, value) !== -1;
}
function indexOf(array, value) {
const index = nativeIndexOf.call(array, value);
return index === -1 ? null : index;
}
function indexOfFn(value) {
return array => indexOf(array, value);
}
function lastIndexOf(array, value) {
for (let i = array.length - 1; i >= 0; --i) {
if (array[i] === value) {
return i;
}
}
return null;
}
function lastIndexOfFn(value) {
return array => lastIndexOf(array, value);
}
function findIndex(array, predicate) {
const index = nativeFindIndex.call(array, predicate);
return index === -1 ? null : index;
}
function findIndexFn(predicate) {
return array => findIndex(array, predicate);
}
function findLastIndex(array, predicate) {
for (let i = array.length - 1; i >= 0; --i) {
if (predicate(array[i], i)) {
return i;
}
}
return null;
}
function findLastIndexFn(predicate) {
return array => findLastIndex(array, predicate);
}
function find(array, predicate) {
const index = findIndex(array, predicate);
return index == null ? null : array[index];
}
function findFn(predicate) {
return array => find(array, predicate);
}
function findLast(array, predicate) {
for (let i = array.length - 1; i >= 0; --i) {
const element = array[i];
if (predicate(element, i)) {
return element;
}
}
return null;
}
function findLastFn(predicate) {
return array => findLast(array, predicate);
}
function maximum(array, compare) {
return internalMaximum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
function maximumFn(compare) {
return array => internalMaximum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
function internalMaximum(array, compare) {
if (array.length === 0) {
return null;
}
let result = array[0];
for (let i = 1; i < array.length; ++i) {
if (compare(array[i], result) > ordered_1.Comparison.equal) {
result = array[i];
}
}
return result;
}
function maximumBy(array, select) {
return maximum(array, (a, b) => (0, ordered_1.compare)(select(a), select(b)));
}
function maximumByFn(select) {
return array => maximumBy(array, select);
}
function minimum(array, compare) {
return internalMinimum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
function minimumFn(compare) {
return array => internalMinimum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
function internalMinimum(array, compare) {
if (array.length === 0) {
return null;
}
let result = array[0];
for (let i = 1; i < array.length; ++i) {
if (compare(array[i], result) < ordered_1.Comparison.equal) {
result = array[i];
}
}
return result;
}
function minimumBy(array, select) {
return minimum(array, (a, b) => (0, ordered_1.compare)(select(a), select(b)));
}
function minimumByFn(select) {
return array => minimumBy(array, select);
}
function sum(array) {
return fold(array, (a, b) => a + b, 0);
}
function product(array) {
return fold(array, (a, b) => a * b, 1);
}
function average(array) {
if (array.length === 0) {
return null;
}
else {
return sum(array) / array.length;
}
}
function and(array) {
return findIndex(array, element => !element) == null;
}
function or(array) {
return findIndex(array, element => Boolean(element)) != null;
}
function any(array, predicate) {
return findIndex(array, predicate) != null;
}
function anyFn(predicate) {
return array => any(array, predicate);
}
function all(array, predicate) {
return !any(array, (element, index) => !predicate(element, index));
}
function allFn(predicate) {
return array => all(array, predicate);
}
function concat(arrays) {
return nativeConcat.apply([], (0, exports.map)(arrays, coerce));
}
function prepend(a) {
return b => concat([a, b]);
}
function append(b) {
return a => concat([a, b]);
}
function concatMap(array, f) {
return concat((0, exports.map)(array, f));
}
function concatMapFn(f) {
return array => concatMap(array, f);
}
function noneNull(array) {
return any(array, nullable_1.isNull) ? null : array;
}
function scan(array, f, initial) {
const result = (0, exports.copy)({ length: array.length });
let accumulator = initial;
for (let i = 0; i < array.length; ++i) {
result[i] = accumulator = f(accumulator, array[i], i);
}
return result;
}
function scanFn(f, initial) {
return array => scan(array, f, initial);
}
function scan1(array, f) {
if (array.length === 0) {
return [];
}
let accumulator = array[0];
const result = (0, exports.copy)({ 0: accumulator, length: array.length });
for (let i = 1; i < array.length; ++i) {
result[i] = accumulator = f(accumulator, array[i], i);
}
return result;
}
function scan1Fn(f) {
return array => scan1(array, f);
}
function scanRight(array, f, initial) {
const result = (0, exports.copy)({ length: array.length });
let accumulator = initial;
for (let i = array.length - 1; i >= 0; --i) {
result[i] = accumulator = f(accumulator, array[i], i);
}
return result;
}
function scanRightFn(f, initial) {
return array => scanRight(array, f, initial);
}
function scanRight1(array, f) {
if (array.length === 0) {
return [];
}
let accumulator = array[array.length - 1];
const result = (0, exports.copy)({ [array.length - 1]: accumulator, length: array.length });
for (let i = array.length - 2; i >= 0; --i) {
result[i] = accumulator = f(accumulator, array[i], i);
}
return result;
}
function scanRight1Fn(f) {
return array => scanRight1(array, f);
}
/** Splits the array at the specified index.
*
* Returns a tuple where the first element is the first `index` elements of the
* array, and the second element is the remaining elements of the array. */
function split(array, index) {
return [take(array, index), drop(array, index)];
}
/** Returns a function that splits an array at the specified index.
*
* This is the curried form of {@link split}. */
function splitFn(index) {
return array => split(array, index);
}
function partition(array, predicate) {
const a = [];
const b = [];
for (let i = 0; i < array.length; ++i) {
if (predicate(array[i], i)) {
a.push(array[i]);
}
else {
b.push(array[i]);
}
}
return [a, b];
}
function partitionFn(predicate) {
return array => partition(array, predicate);
}
function partitionWhile(array, predicate) {
let i;
for (i = 0; i < array.length; ++i) {
if (!predicate(array[i], i)) {
break;
}
}
return [take(array, i), drop(array, i)];
}
function partitionWhileFn(predicate) {
return array => partitionWhile(array, predicate);
}
function partitionUntil(array, predicate) {
return partitionWhile(array, element => !predicate(element));
}
function partitionUntilFn(predicate) {
return array => partitionUntil(array, predicate);
}
/** Takes two arrays and returns an array of corresponding pairs.
*
* If one of the supplied arrays is shorter than the other, then the excess
* elements of the longer array will be discarded. */
function zip(a, b) {
const length = Math.min(a.length, b.length);
const result = new Array(length);
for (let i = 0; i < length; ++i) {
result[i] = [a[i], b[i]];
}
return result;
}
/** Returns a function that combines the elements of `a` with the elements of
* `b` and returns an array of corresponding pairs.
*
* If one of the supplied arrays is shorter than the other, then the excess
* elements of the longer array will be discarded.
*
* This is the curried variant of {@link zip}. */
function zipFn(b) {
return a => zip(a, b);
}
function keyBy(array, f) {
var _a;
const result = new Map();
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const key = f(element, i);
const group = (_a = result.get(key)) !== null && _a !== void 0 ? _a : [];
if (!result.has(key)) {
result.set(key, group);
}
group.push(element);
}
return result;
}
function keyByFn(f) {
return array => keyBy(array, f);
}
function keyFirstBy(array, f) {
const result = new Map();
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const key = f(element, i);
if (!result.has(key)) {
result.set(key, element);
}
}
return result;
}
function keyFirstByFn(f) {
return array => keyFirstBy(array, f);
}
function keyLastBy(array, f) {
const result = new Map();
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const key = f(element, i);
result.set(key, element);
}
return result;
}
function keyLastByFn(f) {
return array => keyLastBy(array, f);
}
function mapKeyBy(array, f) {
var _a;
const result = new Map();
for (let i = 0; i < array.length; ++i) {
const [key, element] = f(array[i], i);
const group = (_a = result.get(key)) !== null && _a !== void 0 ? _a : [];
if (!result.has(key)) {
result.set(key, group);
}
group.push(element);
}
return result;
}
function mapKeyByFn(f) {
return array => mapKeyBy(array, f);
}
function mapKeyFirstBy(array, f) {
const result = new Map();
for (let i = 0; i < array.length; ++i) {
const [key, element] = f(array[i], i);
if (!result.has(key)) {
result.set(key, element);
}
}
return result;
}
function mapKeyFirstByFn(f) {
return array => mapKeyFirstBy(array, f);
}
function mapKeyLastBy(array, f) {
const result = new Map();
for (let i = 0; i < array.length; ++i) {
const [key, element] = f(array[i], i);
result.set(key, element);
}
return result;
}
function mapKeyLastByFn(f) {
return array => mapKeyLastBy(array, f);
}
function group(array, grouping) {
if ("identity" in grouping) {
return groupByIdentity(array, grouping.identity);
}
else if ("compare" in grouping) {
if (typeof grouping.hash === "function") {
return groupByOrderWithHash(array, grouping.compare, grouping.hash);
}
else {
return groupByOrder(array, grouping.compare);
}
}
else if ("equal" in grouping) {
if (typeof grouping.hash === "function") {
return groupByEqualityWithHash(array, grouping.equal, grouping.hash);
}
else {
return groupByEquality(array, grouping.equal);
}
}
else {
return groupByHash(array, grouping.hash);
}
}
function groupFn(grouping) {
return array => group(array, grouping);
}
function groupByIdentity(array, identity = element => element) {
var _a;
const groups = [];
const map = new Map();
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const key = identity(element);
const group = (_a = map.get(key)) !== null && _a !== void 0 ? _a : [];
group.push(element);
if (!map.has(key)) {
groups.push(group);
map.set(key, group);
}
}
return groups;
}
function groupByIdentityFn(identity) {
return array => groupByIdentity(array, identity);
}
function groupByEquality(array, equal) {
const result = [];
outer: for (let i = 0; i < array.length; ++i) {
for (let j = 0; j < result.length; ++j) {
const group = (0, nullable_1.notNull)(result[j]);
if (equal(group[0], array[i])) {
group.push(array[i]);
continue outer;
}
}
result.push([array[i]]);
}
return result;
}
function groupByEqualityFn(equal) {
return array => groupByEquality(array, equal);
}
function groupByOrder(array, compare) {
// TODO: This could use a binary tree to be way more efficient
return groupByEquality(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal);
}
function groupByOrderFn(compare) {
return array => groupByOrder(array, compare);
}
function groupByHash(array, hash) {
var _a;
const groups = new Map();
const result = [];
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const h = hash(element, i);
const group = (_a = groups.get(h)) !== null && _a !== void 0 ? _a : [];
if (!groups.has(h)) {
result.push(group);
groups.set(h, group);
}
group.push(element);
}
return result;
}
function groupByHashFn(hash) {
return array => groupByHash(array, hash);
}
function groupByEqualityWithHash(array, equal, hash) {
var _a;
const groups = new Map();
const result = [];
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const h = hash(element, i);
const hashGroup = (_a = groups.get(h)) !== null && _a !== void 0 ? _a : [];
if (!groups.has(h)) {
groups.set(h, hashGroup);
}
const group = find(hashGroup, group => equal(group[0], element));
if (group == null) {
const newGroup = [element];
hashGroup.push(newGroup);
result.push(newGroup);
}
else {
group.push(element);
}
}
return result;
}
function groupByEqualityWithHashFn(equal, hash) {
return array => groupByEqualityWithHash(array, equal, hash);
}
function groupByOrderWithHash(array, compare, hash) {
return groupByEqualityWithHash(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal, hash);
}
function groupByOrderWithHashFn(compare, hash) {
return array => groupByOrderWithHash(array, compare, hash);
}
function groupAdjacent(array, grouping) {
if ("identity" in grouping) {
return groupAdjacentByIdentity(array, grouping.identity);
}
else if ("equal" in grouping) {
return groupAdjacentByEquality(array, grouping.equal);
}
else if ("compare" in grouping) {
return groupAdjacentByOrder(array, grouping.compare);
}
else {
return groupByHash(array, grouping.hash);
}
}
function groupAdjacentFn(grouping) {
return array => groupAdjacent(array, grouping);
}
function groupAdjacentByIdentity(array, identity) {
return identity == null
? groupAdjacentByEquality(array, (a, b) => a === b)
: groupAdjacentByEquality(array, (a, b) => identity(a) === identity(b));
}
function groupAdjacentByIdentityFn(identity) {
return array => groupAdjacentByEquality(array, (a, b) => identity(a) === identity(b));
}
function groupAdjacentByEquality(array, equal) {
if (array.length === 0) {
return [];
}
let element = array[0];
let group = [element];
const result = [group];
for (let i = 1; i < array.length; ++i) {
const prev = element;
element = array[i];
if (equal(prev, element)) {
group.push(element);
}
else {
group = [element];
result.push(group);
}
}
return result;
}
function groupAdjacentByEqualityFn(equal) {
return array => groupAdjacentByEquality(array, equal);
}
function groupAdjacentByOrder(array, compare) {
return groupAdjacentByEquality(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal);
}
function groupAdjacentByOrderFn(compare) {
return array => groupAdjacentByOrder(array, compare);
}
function groupAdjacentByHash(array, hash) {
if (array.length === 0) {
return [];
}
const element = array[0];
let h = hash(element, 0);
let group = [element];
const result = [group];
for (let i = 1; i < array.length; ++i) {
const element = array[i];
const h1 = hash(element, i);
if (h === h1) {
group.push(element);
}
else {
h = h1;
group = [element];
result.push(group);
}
}
return result;
}
function groupAdjacentByHashFn(hash) {
return array => groupAdjacentByHash(array, hash);
}
function unique(array, grouping) {
if ("identity" in grouping) {
return uniqueByIdentityInternal(array, grouping.identity);
}
else if ("compare" in grouping) {
if (typeof grouping.hash === "function") {
return uniqueByOrderWithHash(array, grouping.compare, grouping.hash);
}
else {
return uniqueByOrder(array, grouping.compare);
}
}
else if ("equal" in grouping) {
if (typeof grouping.hash === "function") {
return uniqueByEqualityWithHash(array, grouping.equal, grouping.hash);
}
else {
return uniqueByEquality(array, grouping.equal);
}
}
else {
return uniqueByHash(array, grouping.hash);
}
}
function uniqueFn(grouping) {
return array => unique(array, grouping);
}
function uniqueByIdentity(array, identity) {
return uniqueByIdentityInternal(array, identity !== null && identity !== void 0 ? identity : (element => element));
}
function uniqueByIdentityInternal(array, identity) {
const set = new Set();
const result = [];
for (let i = 0; i < array.length; ++i) {
const element = array[i];
if (!set.has(identity(element))) {
set.add(identity(element));
result.push(element);
}
}
return result;
}
function uniqueByEquality(array, equal) {
const result = [];
outer: for (let i = 0; i < array.length; ++i) {
const element = array[i];
for (let j = 0; j < result.length; ++j) {
if (equal(element, result[j])) {
continue outer;
}
}
result.push(element);
}
return result;
}
function uniqueByEqualityFn(equal) {
return array => uniqueByEquality(array, equal);
}
function uniqueByOrder(array, compare) {
return uniqueByEquality(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal);
}
function uniqueByOrderFn(compare) {
// TODO: This could use a binary tree to be more efficient
return array => uniqueByOrder(array, compare);
}
function uniqueByHash(array, hash) {
const seen = new Set();
const result = [];
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const h = hash(element, i);
if (!seen.has(h)) {
seen.add(h);
result.push(element);
}
}
return result;
}
function uniqueByHashFn(hash) {
return array => uniqueByHash(array, hash);
}
function uniqueByEqualityWithHash(array, equal, hash) {
var _a;
const seenGroups = new Map();
const result = [];
for (let i = 0; i < array.length; ++i) {
const element = array[i];
const h = hash(element, i);
const seenGroup = (_a = seenGroups.get(h)) !== null && _a !== void 0 ? _a : [];
if (!seenGroups.has(h)) {
seenGroups.set(h, seenGroup);
}
if (all(seenGroup, seenElement => !equal(seenElement, element))) {
seenGroup.push(element);
result.push(element);
}
}
return result;
}
function uniqueByEqualityWithHashFn(equal, hash) {
return array => uniqueByEqualityWithHash(array, equal, hash);
}
function uniqueByOrderWithHash(array, compare, hash) {
return uniqueByEqualityWithHash(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal, hash);
}
function uniqueByOrderWithHashFn(compare, hash) {
return array => uniqueByOrderWithHash(array, compare, hash);
}
function uniqueAdjacent(array, grouping) {
if ("identity" in grouping) {
return uniqueAdjacentByIdentity(array, grouping.identity);
}
else if ("equal" in grouping) {
return uniqueAdjacentByEquality(array, grouping.equal);
}
else if ("compare" in grouping) {
return uniqueAdjacentByOrder(array, grouping.compare);
}
else {
return uniqueAdjacentByHash(array, grouping.hash);
}
}
function uniqueAdjacentFn(grouping) {
return array => uniqueAdjacent(array, grouping);
}
function uniqueAdjacentByIdentity(array, identity) {
return identity == null
? uniqueAdjacentByEquality(array, (a, b) => a === b)
: uniqueAdjacentByEquality(array, (a, b) => identity(a) === identity(b));
}
function uniqueAdjacentByIdentityFn(identity) {
return array => uniqueAdjacentByIdentity(array, identity);
}
function uniqueAdjacentByEquality(array, equal) {
if (array.length === 0) {
return [];
}
let element = array[0];
const result = [element];
for (let i = 1; i < array.length; ++i) {
const prev = element;
element = array[i];
if (!equal(prev, element)) {
result.push(element);
}
}
return result;
}
function uniqueAdjacentByEqualityFn(equal) {
return array => uniqueAdjacentByEquality(array, equal);
}
function uniqueAdjacentByOrder(array, compare) {
return uniqueAdjacentByEquality(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal);
}
function uniqueAdjacentByOrderFn(compare) {
return array => uniqueAdjacentByOrder(array, compare);
}
function uniqueAdjacentByHash(array, hash) {
if (array.length === 0) {
return [];
}
const element = array[0];
let h = hash(element, 0);
const result = [element];
for (let i = 1; i < array.length; ++i) {
const element = array[i];
const h1 = hash(element, i);
if (h !== h1) {
h = h1;
result.push(element);
}
}
return result;
}
function uniqueAdjacentByHashFn(hash) {
return array => uniqueAdjacentByHash(array, hash);
}
function sort(array, comparator) {
return (0, exports.copy)(array).sort(comparator !== null && comparator !== void 0 ? comparator : ordered_1.compare);
}
function sortFn(comparator) {
return array => sort(array, comparator);
}
function sortBy(array, select) {
return sort(array, (a, b) => ordered_1.compare(select(a), select(b)));
}
function sortByFn(select) {
return array => sortBy(array, select);
}
function sortByDescending(array, select) {
return sort(array, (a, b) => -ordered_1.compare(select(a), select(b)));
}
function sortByDescendingFn(select) {
return array => sortByDescending(array, select);
}
function forEach(array, f) {
for (let i = 0; i < array.length; ++i) {
f(array[i], i);
}
return array;
}
function forEachFn(f) {
return array => forEach(array, f);
}
//# sourceMappingURL=index.js.map