@softwareventures/array
Version:
Pure functional array manipulation and traversal
1,209 lines • 41.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.fold = exports.removeFirstFn = exports.removeFirst = exports.removeFn = exports.remove = exports.excludeFirstFn = exports.excludeFirst = exports.excludeNull = exports.excludeFn = exports.exclude = exports.filterFn = exports.filter = exports.mapFn = exports.map = exports.prefixMatchFn = exports.prefixMatch = exports.notEqualFn = exports.notEqual = exports.equalFn = exports.equal = exports.dropUntilFn = exports.dropUntil = exports.dropWhileFn = exports.dropWhile = exports.takeUntilFn = exports.takeUntil = exports.takeWhileFn = exports.takeWhile = exports.dropFn = exports.drop = exports.takeFn = exports.take = exports.sliceFn = exports.slice = exports.reverse = exports.notEmpty = exports.empty = exports.only = exports.last = exports.initial = exports.unshiftFn = exports.unshift = exports.pushFn = exports.push = exports.tail = exports.first = exports.coerce = exports.isArrayLike = exports.isArray = exports.copy = void 0;
exports.scanFn = exports.scan = exports.noneNull = exports.concatMapFn = exports.concatMap = exports.append = exports.prepend = exports.concat = exports.allFn = exports.all = exports.anyFn = exports.any = exports.or = exports.and = exports.average = exports.product = exports.sum = exports.minimumByFn = exports.minimumBy = exports.minimumFn = exports.minimum = exports.maximumByFn = exports.maximumBy = exports.maximumFn = exports.maximum = exports.findLastFn = exports.findLast = exports.findFn = exports.find = exports.findLastIndexFn = exports.findLastIndex = exports.findIndexFn = exports.findIndex = exports.lastIndexOfFn = exports.lastIndexOf = exports.indexOfFn = exports.indexOf = exports.containsFn = exports.contains = exports.foldMapRightFn = exports.foldMapRight = exports.foldMapFn = exports.foldMap = exports.foldRight1Fn = exports.foldRight1 = exports.foldRightFn = exports.foldRight = exports.fold1Fn = exports.fold1 = exports.foldFn = void 0;
exports.groupAdjacentByOrderFn = exports.groupAdjacentByOrder = exports.groupAdjacentByEqualityFn = exports.groupAdjacentByEquality = exports.groupAdjacentByIdentityFn = exports.groupAdjacentByIdentity = exports.groupAdjacentFn = exports.groupAdjacent = exports.groupByOrderWithHashFn = exports.groupByOrderWithHash = exports.groupByEqualityWithHashFn = exports.groupByEqualityWithHash = exports.groupByHashFn = exports.groupByHash = exports.groupByOrderFn = exports.groupByOrder = exports.groupByEqualityFn = exports.groupByEquality = exports.groupByIdentityFn = exports.groupByIdentity = exports.groupFn = exports.group = exports.mapKeyLastByFn = exports.mapKeyLastBy = exports.mapKeyFirstByFn = exports.mapKeyFirstBy = exports.mapKeyByFn = exports.mapKeyBy = exports.keyLastByFn = exports.keyLastBy = exports.keyFirstByFn = exports.keyFirstBy = exports.keyByFn = exports.keyBy = exports.zipFn = exports.zip = exports.partitionUntilFn = exports.partitionUntil = exports.partitionWhileFn = exports.partitionWhile = exports.partitionFn = exports.partition = exports.splitFn = exports.split = exports.scanRight1Fn = exports.scanRight1 = exports.scanRightFn = exports.scanRight = exports.scan1Fn = exports.scan1 = void 0;
exports.forEachFn = exports.forEach = exports.sortByDescendingFn = exports.sortByDescending = exports.sortByFn = exports.sortBy = exports.sortFn = exports.sort = exports.uniqueAdjacentByHashFn = exports.uniqueAdjacentByHash = exports.uniqueAdjacentByOrderFn = exports.uniqueAdjacentByOrder = exports.uniqueAdjacentByEqualityFn = exports.uniqueAdjacentByEquality = exports.uniqueAdjacentByIdentityFn = exports.uniqueAdjacentByIdentity = exports.uniqueAdjacentFn = exports.uniqueAdjacent = exports.uniqueByOrderWithHashFn = exports.uniqueByOrderWithHash = exports.uniqueByEqualityWithHashFn = exports.uniqueByEqualityWithHash = exports.uniqueByHashFn = exports.uniqueByHash = exports.uniqueByOrderFn = exports.uniqueByOrder = exports.uniqueByEqualityFn = exports.uniqueByEquality = exports.uniqueByIdentity = exports.uniqueFn = exports.unique = exports.groupAdjacentByHashFn = exports.groupAdjacentByHash = void 0;
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");
}
exports.isArrayLike = isArrayLike;
function coerce(array) {
return (0, exports.isArray)(array) ? array : (0, exports.copy)(array);
}
exports.coerce = coerce;
function first(array) {
return array.length === 0 ? null : array[0];
}
exports.first = first;
function tail(array) {
return nativeSlice.call(array, 1);
}
exports.tail = tail;
function push(array, value) {
return [...coerce(array), value];
}
exports.push = push;
function pushFn(value) {
return array => push(array, value);
}
exports.pushFn = pushFn;
function unshift(array, value) {
return [value, ...coerce(array)];
}
exports.unshift = unshift;
function unshiftFn(value) {
return array => unshift(array, value);
}
exports.unshiftFn = unshiftFn;
function initial(array) {
return array.length === 0 ? [] : nativeSlice.call(array, 0, array.length - 1);
}
exports.initial = initial;
function last(array) {
return array.length === 0 ? null : array[array.length - 1];
}
exports.last = last;
/** If the array contains exactly one element, returns that element.
* Otherwise, returns null. */
function only(array) {
return array.length === 1 ? array[0] : null;
}
exports.only = only;
function empty(array) {
return array.length === 0;
}
exports.empty = empty;
function notEmpty(array) {
return array.length > 0;
}
exports.notEmpty = notEmpty;
function reverse(array) {
return nativeReverse.call((0, exports.copy)(array));
}
exports.reverse = reverse;
function slice(array, start, end) {
return nativeSlice.call(array, start, end);
}
exports.slice = slice;
function sliceFn(start, end) {
return array => nativeSlice.call(array, start, end);
}
exports.sliceFn = sliceFn;
function take(array, count) {
return nativeSlice.call(array, 0, count);
}
exports.take = take;
function takeFn(count) {
return array => nativeSlice.call(array, 0, count);
}
exports.takeFn = takeFn;
function drop(array, count) {
return nativeSlice.call(array, count);
}
exports.drop = drop;
function dropFn(count) {
return array => nativeSlice.call(array, count);
}
exports.dropFn = dropFn;
function takeWhile(array, predicate) {
let i = 0;
while (i < array.length && predicate(array[i], i)) {
++i;
}
return take(array, i);
}
exports.takeWhile = takeWhile;
function takeWhileFn(predicate) {
return array => takeWhile(array, predicate);
}
exports.takeWhileFn = takeWhileFn;
function takeUntil(array, predicate) {
return takeWhile(array, (element, index) => !predicate(element, index));
}
exports.takeUntil = takeUntil;
function takeUntilFn(predicate) {
return array => takeUntil(array, predicate);
}
exports.takeUntilFn = takeUntilFn;
function dropWhile(array, predicate) {
let i = 0;
while (i < array.length && predicate(array[i], i)) {
++i;
}
return drop(array, i);
}
exports.dropWhile = dropWhile;
function dropWhileFn(predicate) {
return array => dropWhile(array, predicate);
}
exports.dropWhileFn = dropWhileFn;
function dropUntil(array, predicate) {
return dropWhile(array, (element, index) => !predicate(element, index));
}
exports.dropUntil = dropUntil;
function dropUntilFn(predicate) {
return array => dropWhile(array, predicate);
}
exports.dropUntilFn = dropUntilFn;
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;
}
exports.equal = equal;
function equalFn(b, elementsEqual = ordered_1.equal) {
return a => equal(a, b, elementsEqual);
}
exports.equalFn = equalFn;
function notEqual(a, b, elementsEqual = ordered_1.equal) {
return !equal(a, b, elementsEqual);
}
exports.notEqual = notEqual;
function notEqualFn(b, elementsEqual = ordered_1.equal) {
return a => notEqual(a, b, elementsEqual);
}
exports.notEqualFn = notEqualFn;
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;
}
exports.prefixMatch = prefixMatch;
function prefixMatchFn(b, elementsEqual = ordered_1.equal) {
return a => prefixMatch(a, b, elementsEqual);
}
exports.prefixMatchFn = prefixMatchFn;
/** @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);
}
exports.mapFn = mapFn;
function filter(array, predicate) {
return nativeFilter.call(array, predicate);
}
exports.filter = filter;
function filterFn(predicate) {
return array => nativeFilter.call(array, predicate);
}
exports.filterFn = filterFn;
function exclude(array, predicate) {
return filter(array, (element, index) => !predicate(element, index));
}
exports.exclude = exclude;
function excludeFn(predicate) {
return array => exclude(array, predicate);
}
exports.excludeFn = excludeFn;
function excludeNull(array) {
return filter(array, nullable_1.isNotNull);
}
exports.excludeNull = excludeNull;
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;
}
exports.excludeFirst = excludeFirst;
function excludeFirstFn(predicate) {
return array => excludeFirst(array, predicate);
}
exports.excludeFirstFn = excludeFirstFn;
function remove(array, value) {
return exclude(array, element => element === value);
}
exports.remove = remove;
function removeFn(value) {
return array => remove(array, value);
}
exports.removeFn = removeFn;
function removeFirst(array, value) {
return excludeFirst(array, element => element === value);
}
exports.removeFirst = removeFirst;
function removeFirstFn(value) {
return array => removeFirst(array, value);
}
exports.removeFirstFn = removeFirstFn;
function fold(array, f, initial) {
return nativeReduce.call(array, f, initial);
}
exports.fold = fold;
function foldFn(f, initial) {
return array => nativeReduce.call(array, f, initial);
}
exports.foldFn = foldFn;
function fold1(array, f) {
return nativeReduce.call(array, f);
}
exports.fold1 = fold1;
function fold1Fn(f) {
return array => fold1(array, f);
}
exports.fold1Fn = fold1Fn;
function foldRight(array, f, initial) {
return nativeReduceRight.call(array, f, initial);
}
exports.foldRight = foldRight;
function foldRightFn(f, initial) {
return array => nativeReduceRight.call(array, f, initial);
}
exports.foldRightFn = foldRightFn;
function foldRight1(array, f) {
return nativeReduceRight.call(array, f);
}
exports.foldRight1 = foldRight1;
function foldRight1Fn(f) {
return array => foldRight1(array, f);
}
exports.foldRight1Fn = foldRight1Fn;
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;
}
exports.foldMap = foldMap;
function foldMapFn(f, m, initial) {
return array => foldMap(array, f, m, initial);
}
exports.foldMapFn = foldMapFn;
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;
}
exports.foldMapRight = foldMapRight;
function foldMapRightFn(f, m, initial) {
return array => foldMapRight(array, f, m, initial);
}
exports.foldMapRightFn = foldMapRightFn;
function contains(array, value) {
return nativeIndexOf.call(array, value) !== -1;
}
exports.contains = contains;
function containsFn(value) {
return array => nativeIndexOf.call(array, value) !== -1;
}
exports.containsFn = containsFn;
function indexOf(array, value) {
const index = nativeIndexOf.call(array, value);
return index === -1 ? null : index;
}
exports.indexOf = indexOf;
function indexOfFn(value) {
return array => indexOf(array, value);
}
exports.indexOfFn = indexOfFn;
function lastIndexOf(array, value) {
for (let i = array.length - 1; i >= 0; --i) {
if (array[i] === value) {
return i;
}
}
return null;
}
exports.lastIndexOf = lastIndexOf;
function lastIndexOfFn(value) {
return array => lastIndexOf(array, value);
}
exports.lastIndexOfFn = lastIndexOfFn;
function findIndex(array, predicate) {
const index = nativeFindIndex.call(array, predicate);
return index === -1 ? null : index;
}
exports.findIndex = findIndex;
function findIndexFn(predicate) {
return array => findIndex(array, predicate);
}
exports.findIndexFn = findIndexFn;
function findLastIndex(array, predicate) {
for (let i = array.length - 1; i >= 0; --i) {
if (predicate(array[i], i)) {
return i;
}
}
return null;
}
exports.findLastIndex = findLastIndex;
function findLastIndexFn(predicate) {
return array => findLastIndex(array, predicate);
}
exports.findLastIndexFn = findLastIndexFn;
function find(array, predicate) {
const index = findIndex(array, predicate);
return index == null ? null : array[index];
}
exports.find = find;
function findFn(predicate) {
return array => find(array, predicate);
}
exports.findFn = findFn;
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;
}
exports.findLast = findLast;
function findLastFn(predicate) {
return array => findLast(array, predicate);
}
exports.findLastFn = findLastFn;
function maximum(array, compare) {
return internalMaximum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
exports.maximum = maximum;
function maximumFn(compare) {
return array => internalMaximum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
exports.maximumFn = maximumFn;
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)));
}
exports.maximumBy = maximumBy;
function maximumByFn(select) {
return array => maximumBy(array, select);
}
exports.maximumByFn = maximumByFn;
function minimum(array, compare) {
return internalMinimum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
exports.minimum = minimum;
function minimumFn(compare) {
return array => internalMinimum(array, compare !== null && compare !== void 0 ? compare : ordered_1.compare);
}
exports.minimumFn = minimumFn;
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)));
}
exports.minimumBy = minimumBy;
function minimumByFn(select) {
return array => minimumBy(array, select);
}
exports.minimumByFn = minimumByFn;
function sum(array) {
return fold(array, (a, b) => a + b, 0);
}
exports.sum = sum;
function product(array) {
return fold(array, (a, b) => a * b, 1);
}
exports.product = product;
function average(array) {
if (array.length === 0) {
return null;
}
else {
return sum(array) / array.length;
}
}
exports.average = average;
function and(array) {
return findIndex(array, element => !element) == null;
}
exports.and = and;
function or(array) {
return findIndex(array, element => Boolean(element)) != null;
}
exports.or = or;
function any(array, predicate) {
return findIndex(array, predicate) != null;
}
exports.any = any;
function anyFn(predicate) {
return array => any(array, predicate);
}
exports.anyFn = anyFn;
function all(array, predicate) {
return !any(array, (element, index) => !predicate(element, index));
}
exports.all = all;
function allFn(predicate) {
return array => all(array, predicate);
}
exports.allFn = allFn;
function concat(arrays) {
return nativeConcat.apply([], (0, exports.map)(arrays, coerce));
}
exports.concat = concat;
function prepend(a) {
return b => concat([a, b]);
}
exports.prepend = prepend;
function append(b) {
return a => concat([a, b]);
}
exports.append = append;
function concatMap(array, f) {
return concat((0, exports.map)(array, f));
}
exports.concatMap = concatMap;
function concatMapFn(f) {
return array => concatMap(array, f);
}
exports.concatMapFn = concatMapFn;
function noneNull(array) {
return any(array, nullable_1.isNull) ? null : array;
}
exports.noneNull = noneNull;
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;
}
exports.scan = scan;
function scanFn(f, initial) {
return array => scan(array, f, initial);
}
exports.scanFn = scanFn;
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;
}
exports.scan1 = scan1;
function scan1Fn(f) {
return array => scan1(array, f);
}
exports.scan1Fn = scan1Fn;
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;
}
exports.scanRight = scanRight;
function scanRightFn(f, initial) {
return array => scanRight(array, f, initial);
}
exports.scanRightFn = scanRightFn;
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;
}
exports.scanRight1 = scanRight1;
function scanRight1Fn(f) {
return array => scanRight1(array, f);
}
exports.scanRight1Fn = scanRight1Fn;
/** 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)];
}
exports.split = split;
/** 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);
}
exports.splitFn = splitFn;
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];
}
exports.partition = partition;
function partitionFn(predicate) {
return array => partition(array, predicate);
}
exports.partitionFn = partitionFn;
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)];
}
exports.partitionWhile = partitionWhile;
function partitionWhileFn(predicate) {
return array => partitionWhile(array, predicate);
}
exports.partitionWhileFn = partitionWhileFn;
function partitionUntil(array, predicate) {
return partitionWhile(array, element => !predicate(element));
}
exports.partitionUntil = partitionUntil;
function partitionUntilFn(predicate) {
return array => partitionUntil(array, predicate);
}
exports.partitionUntilFn = partitionUntilFn;
/** 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;
}
exports.zip = zip;
/** 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);
}
exports.zipFn = zipFn;
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;
}
exports.keyBy = keyBy;
function keyByFn(f) {
return array => keyBy(array, f);
}
exports.keyByFn = keyByFn;
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;
}
exports.keyFirstBy = keyFirstBy;
function keyFirstByFn(f) {
return array => keyFirstBy(array, f);
}
exports.keyFirstByFn = keyFirstByFn;
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;
}
exports.keyLastBy = keyLastBy;
function keyLastByFn(f) {
return array => keyLastBy(array, f);
}
exports.keyLastByFn = keyLastByFn;
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;
}
exports.mapKeyBy = mapKeyBy;
function mapKeyByFn(f) {
return array => mapKeyBy(array, f);
}
exports.mapKeyByFn = mapKeyByFn;
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;
}
exports.mapKeyFirstBy = mapKeyFirstBy;
function mapKeyFirstByFn(f) {
return array => mapKeyFirstBy(array, f);
}
exports.mapKeyFirstByFn = mapKeyFirstByFn;
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;
}
exports.mapKeyLastBy = mapKeyLastBy;
function mapKeyLastByFn(f) {
return array => mapKeyLastBy(array, f);
}
exports.mapKeyLastByFn = mapKeyLastByFn;
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);
}
}
exports.group = group;
function groupFn(grouping) {
return array => group(array, grouping);
}
exports.groupFn = groupFn;
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;
}
exports.groupByIdentity = groupByIdentity;
function groupByIdentityFn(identity) {
return array => groupByIdentity(array, identity);
}
exports.groupByIdentityFn = groupByIdentityFn;
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;
}
exports.groupByEquality = groupByEquality;
function groupByEqualityFn(equal) {
return array => groupByEquality(array, equal);
}
exports.groupByEqualityFn = groupByEqualityFn;
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);
}
exports.groupByOrder = groupByOrder;
function groupByOrderFn(compare) {
return array => groupByOrder(array, compare);
}
exports.groupByOrderFn = groupByOrderFn;
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;
}
exports.groupByHash = groupByHash;
function groupByHashFn(hash) {
return array => groupByHash(array, hash);
}
exports.groupByHashFn = groupByHashFn;
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;
}
exports.groupByEqualityWithHash = groupByEqualityWithHash;
function groupByEqualityWithHashFn(equal, hash) {
return array => groupByEqualityWithHash(array, equal, hash);
}
exports.groupByEqualityWithHashFn = groupByEqualityWithHashFn;
function groupByOrderWithHash(array, compare, hash) {
return groupByEqualityWithHash(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal, hash);
}
exports.groupByOrderWithHash = groupByOrderWithHash;
function groupByOrderWithHashFn(compare, hash) {
return array => groupByOrderWithHash(array, compare, hash);
}
exports.groupByOrderWithHashFn = groupByOrderWithHashFn;
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);
}
}
exports.groupAdjacent = groupAdjacent;
function groupAdjacentFn(grouping) {
return array => groupAdjacent(array, grouping);
}
exports.groupAdjacentFn = groupAdjacentFn;
function groupAdjacentByIdentity(array, identity) {
return identity == null
? groupAdjacentByEquality(array, (a, b) => a === b)
: groupAdjacentByEquality(array, (a, b) => identity(a) === identity(b));
}
exports.groupAdjacentByIdentity = groupAdjacentByIdentity;
function groupAdjacentByIdentityFn(identity) {
return array => groupAdjacentByEquality(array, (a, b) => identity(a) === identity(b));
}
exports.groupAdjacentByIdentityFn = groupAdjacentByIdentityFn;
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;
}
exports.groupAdjacentByEquality = groupAdjacentByEquality;
function groupAdjacentByEqualityFn(equal) {
return array => groupAdjacentByEquality(array, equal);
}
exports.groupAdjacentByEqualityFn = groupAdjacentByEqualityFn;
function groupAdjacentByOrder(array, compare) {
return groupAdjacentByEquality(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal);
}
exports.groupAdjacentByOrder = groupAdjacentByOrder;
function groupAdjacentByOrderFn(compare) {
return array => groupAdjacentByOrder(array, compare);
}
exports.groupAdjacentByOrderFn = groupAdjacentByOrderFn;
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;
}
exports.groupAdjacentByHash = groupAdjacentByHash;
function groupAdjacentByHashFn(hash) {
return array => groupAdjacentByHash(array, hash);
}
exports.groupAdjacentByHashFn = groupAdjacentByHashFn;
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);
}
}
exports.unique = unique;
function uniqueFn(grouping) {
return array => unique(array, grouping);
}
exports.uniqueFn = uniqueFn;
function uniqueByIdentity(array, identity) {
return uniqueByIdentityInternal(array, identity !== null && identity !== void 0 ? identity : (element => element));
}
exports.uniqueByIdentity = uniqueByIdentity;
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;
}
exports.uniqueByEquality = uniqueByEquality;
function uniqueByEqualityFn(equal) {
return array => uniqueByEquality(array, equal);
}
exports.uniqueByEqualityFn = uniqueByEqualityFn;
function uniqueByOrder(array, compare) {
return uniqueByEquality(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal);
}
exports.uniqueByOrder = uniqueByOrder;
function uniqueByOrderFn(compare) {
// TODO: This could use a binary tree to be more efficient
return array => uniqueByOrder(array, compare);
}
exports.uniqueByOrderFn = uniqueByOrderFn;
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;
}
exports.uniqueByHash = uniqueByHash;
function uniqueByHashFn(hash) {
return array => uniqueByHash(array, hash);
}
exports.uniqueByHashFn = uniqueByHashFn;
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;
}
exports.uniqueByEqualityWithHash = uniqueByEqualityWithHash;
function uniqueByEqualityWithHashFn(equal, hash) {
return array => uniqueByEqualityWithHash(array, equal, hash);
}
exports.uniqueByEqualityWithHashFn = uniqueByEqualityWithHashFn;
function uniqueByOrderWithHash(array, compare, hash) {
return uniqueByEqualityWithHash(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal, hash);
}
exports.uniqueByOrderWithHash = uniqueByOrderWithHash;
function uniqueByOrderWithHashFn(compare, hash) {
return array => uniqueByOrderWithHash(array, compare, hash);
}
exports.uniqueByOrderWithHashFn = uniqueByOrderWithHashFn;
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);
}
}
exports.uniqueAdjacent = uniqueAdjacent;
function uniqueAdjacentFn(grouping) {
return array => uniqueAdjacent(array, grouping);
}
exports.uniqueAdjacentFn = uniqueAdjacentFn;
function uniqueAdjacentByIdentity(array, identity) {
return identity == null
? uniqueAdjacentByEquality(array, (a, b) => a === b)
: uniqueAdjacentByEquality(array, (a, b) => identity(a) === identity(b));
}
exports.uniqueAdjacentByIdentity = uniqueAdjacentByIdentity;
function uniqueAdjacentByIdentityFn(identity) {
return array => uniqueAdjacentByIdentity(array, identity);
}
exports.uniqueAdjacentByIdentityFn = uniqueAdjacentByIdentityFn;
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;
}
exports.uniqueAdjacentByEquality = uniqueAdjacentByEquality;
function uniqueAdjacentByEqualityFn(equal) {
return array => uniqueAdjacentByEquality(array, equal);
}
exports.uniqueAdjacentByEqualityFn = uniqueAdjacentByEqualityFn;
function uniqueAdjacentByOrder(array, compare) {
return uniqueAdjacentByEquality(array, (a, b) => compare(a, b) === ordered_1.Comparison.equal);
}
exports.uniqueAdjacentByOrder = uniqueAdjacentByOrder;
function uniqueAdjacentByOrderFn(compare) {
return array => uniqueAdjacentByOrder(array, compare);
}
exports.uniqueAdjacentByOrderFn = uniqueAdjacentByOrderFn;
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;
}
exports.uniqueAdjacentByHash = uniqueAdjacentByHash;
function uniqueAdjacentByHashFn(hash) {
return array => uniqueAdjacentByHash(array, hash);
}
exports.uniqueAdjacentByHashFn = uniqueAdjacentByHashFn;
function sort(array, comparator) {
return (0, exports.copy)(array).sort(comparator !== null && comparator !== void 0 ? comparator : ordered_1.compare);
}
exports.sort = sort;
function sortFn(comparator) {
return array => sort(array, comparator);
}
exports.sortFn = sortFn;
function sortBy(array, select) {
return sort(array, (a, b) => ordered_1.compare(select(a), select(b)));
}
exports.sortBy = sortBy;
function sortByFn(select) {
return array => sortBy(array, select);
}
exports.sortByFn = sortByFn;
function sortByDescending(array, select) {
return sort(array, (a, b) => -ordered_1.compare(select(a), select(b)));
}
exports.sortByDescending = sortByDescending;
function sortByDescendingFn(select) {
return array => sortByDescending(array, select);
}
exports.sortByDescendingFn = sortByDescendingFn;
function forEach(array, f) {
for (let i = 0; i < array.length; ++i) {
f(array[i], i);
}
return array;
}
exports.forEach = forEach;
function forEachFn(f) {
return array => forEach(array, f);
}
exports.forEachFn = forEachFn;
//# sourceMappingURL=index.js.map