ts-data-forge
Version:
[](https://www.npmjs.com/package/ts-data-forge) [](https://www.npmjs.com/package/ts-data-forge) [ • 10.7 kB
JavaScript
import '../../collections/imap-mapped.mjs';
import { IMap } from '../../collections/imap.mjs';
import '../../collections/iset-mapped.mjs';
import '../../collections/iset.mjs';
import '@sindresorhus/is';
import { castMutable } from '../../others/cast-mutable.mjs';
import { tp } from '../../others/tuple.mjs';
import '../../number/branded-types/finite-number.mjs';
import '../../number/branded-types/int.mjs';
import '../../number/branded-types/int16.mjs';
import '../../number/branded-types/int32.mjs';
import '../../number/branded-types/non-negative-finite-number.mjs';
import '../../number/branded-types/non-negative-int16.mjs';
import '../../number/branded-types/non-negative-int32.mjs';
import '../../number/branded-types/non-zero-finite-number.mjs';
import '../../number/branded-types/non-zero-int.mjs';
import '../../number/branded-types/non-zero-int16.mjs';
import '../../number/branded-types/non-zero-int32.mjs';
import '../../number/branded-types/non-zero-safe-int.mjs';
import '../../number/branded-types/non-zero-uint16.mjs';
import '../../number/branded-types/non-zero-uint32.mjs';
import '../../number/branded-types/positive-finite-number.mjs';
import '../../number/branded-types/positive-int.mjs';
import '../../number/branded-types/positive-int16.mjs';
import '../../number/branded-types/positive-int32.mjs';
import '../../number/branded-types/positive-safe-int.mjs';
import '../../number/branded-types/positive-uint16.mjs';
import { asPositiveUint32 } from '../../number/branded-types/positive-uint32.mjs';
import '../../number/branded-types/safe-int.mjs';
import '../../number/branded-types/safe-uint.mjs';
import '../../number/branded-types/uint.mjs';
import '../../number/branded-types/uint16.mjs';
import { asUint32, Uint32 } from '../../number/branded-types/uint32.mjs';
import '../../number/enum/int8.mjs';
import '../../number/enum/uint8.mjs';
import '../../number/num.mjs';
import '../../number/refined-number-utils.mjs';
import { seq, newArray } from './array-utils-creation.mjs';
import { size } from './array-utils-size.mjs';
function map(...args) {
switch (args.length) {
case 2: {
const [array, mapFn] = args;
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
return array.map(mapFn);
}
case 1: {
const [mapFn] = args;
return (array) => map(array, mapFn);
}
}
}
function scan(...args) {
switch (args.length) {
case 3: {
const [array, reducer, init] = args;
const mut_result = castMutable(newArray(asPositiveUint32(array.length + 1), init));
let mut_acc = init;
for (const [index, value] of array.entries()) {
mut_acc = reducer(mut_acc, value, asUint32(index));
mut_result[index + 1] = mut_acc;
}
return mut_result;
}
case 2: {
const [reducer, init] = args;
return (array) => scan(array, reducer, init);
}
}
}
/**
* Reverses an array.
*
* @example
*
* ```ts
* const tuple = [1, 'two', true] as const;
*
* const reversed = Arr.toReversed(tuple);
*
* const expected = [true, 'two', 1] as const;
*
* assert.deepStrictEqual(reversed, expected);
* ```
*/
const toReversed = (array) =>
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
array.toReversed();
/**
* Sorts an array.
*
* @example
*
* ```ts
* const numbers = [3, 1, 2] as const;
*
* const words = ['banana', 'apple', 'cherry'] as const;
*
* const ascendingNumbers = Arr.toSorted(numbers);
*
* const alphabetical = Arr.toSorted(words, (left, right) =>
* left.localeCompare(right),
* );
*
* const expectedNumbers = [1, 2, 3] as const;
*
* const expectedWords = ['apple', 'banana', 'cherry'] as const;
*
* assert.deepStrictEqual(ascendingNumbers, expectedNumbers);
*
* assert.deepStrictEqual(alphabetical, expectedWords);
* ```
*/
const toSorted = (...[array, comparator]) =>
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
array.toSorted(
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
comparator ??
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
((x, y) => x - y));
function toSortedBy(array, comparatorValueMapper, comparator) {
return array.toSorted((x, y) => comparator === undefined
? // This branch assumes V is number if comparator is undefined.
// The overloads should handle this, but explicit cast might be needed if V is not number.
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
comparatorValueMapper(x) -
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
comparatorValueMapper(y)
: comparator(comparatorValueMapper(x), comparatorValueMapper(y)));
}
function filter(...args) {
switch (args.length) {
case 2: {
const [array, predicate] = args;
return array.filter((a, i) => predicate(a, asUint32(i)));
}
case 1: {
const [predicate] = args;
return (array) => filter(array, predicate);
}
}
}
function filterNot(...args) {
switch (args.length) {
case 2: {
const [array, predicate] = args;
return array.filter((a, i) => !predicate(a, asUint32(i)));
}
case 1: {
const [predicate] = args;
return (array) => filterNot(array, predicate);
}
}
}
/**
* Creates a new array with unique elements.
*
* @example
*
* ```ts
* const letters = ['a', 'b', 'a', 'c', 'b'] as const;
*
* const uniqueLetters = Arr.uniq(letters);
*
* const expected = ['a', 'b', 'c'] as const;
*
* assert.deepStrictEqual(uniqueLetters, expected);
* ```
*/
const uniq = (array) =>
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
Array.from(new Set(array));
/**
* Creates a new array with unique elements based on a mapped value.
*
* @example
*
* ```ts
* const people = [
* { id: 1, name: 'Ada' },
* { id: 2, name: 'Brian' },
* { id: 1, name: 'Alan' },
* { id: 3, name: 'Grace' },
* ] as const;
*
* const uniqueById = Arr.uniqBy(people, (person) => person.id);
*
* const expected = [
* { id: 1, name: 'Ada' },
* { id: 2, name: 'Brian' },
* { id: 3, name: 'Grace' },
* ] as const;
*
* assert.deepStrictEqual(uniqueById, expected);
* ```
*/
const uniqBy = (array, mapFn) => {
const mut_mappedValues = new Set();
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
return array.filter((val) => {
const mappedValue = mapFn(val);
if (mut_mappedValues.has(mappedValue))
return false;
mut_mappedValues.add(mappedValue);
return true;
});
};
function flat(...args) {
switch (args.length) {
case 2: {
const [array, depth] = args;
return array.flat(depth);
}
case 1: {
const [arrayOrDepth] = args;
if (typeof arrayOrDepth === 'number') {
const depth = arrayOrDepth;
return (array) => flat(array, depth);
}
else if (arrayOrDepth === undefined) {
return (array) => flat(array, 1);
}
else {
return arrayOrDepth.flat();
}
}
case 0:
return (array) => flat(array, 1);
}
}
function flatMap(...args) {
switch (args.length) {
case 2: {
const [array, mapFn] = args;
return array.flatMap((a, i) => mapFn(a, asUint32(i)));
}
case 1: {
const [mapFn] = args;
return (array) => flatMap(array, mapFn);
}
}
}
function partition(...args) {
switch (args.length) {
case 2: {
const [array, chunkSize] = args;
return chunkSize < 2
? []
: // eslint-disable-next-line total-functions/no-partial-division
seq(asUint32(Math.ceil(array.length / chunkSize))).map((i) => array.slice(chunkSize * i, chunkSize * (i + 1)));
}
case 1: {
const [chunkSize] = args;
return (array) => partition(array, chunkSize);
}
}
}
/**
* Concatenates two arrays.
*
* @example
*
* ```ts
* const numbers = [1, 2] as const;
*
* const words = ['three', 'four'] as const;
*
* const combined = Arr.concat(numbers, words);
*
* const expectedCombined = [1, 2, 'three', 'four'] as const;
*
* assert.deepStrictEqual(combined, expectedCombined);
* ```
*/
const concat = (array1, array2) => [...array1, ...array2];
function groupBy(...args) {
switch (args.length) {
case 2: {
const [array, grouper] = args;
const mut_groups = new Map(); // Store mutable arrays internally
for (const [index, e] of array.entries()) {
const key = grouper(e, asUint32(index)); // Ensure index is treated as SizeType.Arr
const mut_group = mut_groups.get(key);
if (mut_group !== undefined) {
mut_group.push(e);
}
else {
mut_groups.set(key, [e]);
}
}
// Cast to IMap<G, readonly A[]> for the public interface
return IMap.create(mut_groups);
}
case 1: {
const [grouper] = args;
return (array) => groupBy(array, grouper);
}
}
}
/**
* Creates an array of tuples by pairing corresponding elements from two arrays.
*
* @example
*
* ```ts
* const letters = ['a', 'b', 'c'] as const;
*
* const numbers = [1, 2, 3] as const;
*
* const pairs = Arr.zip(letters, numbers);
*
* const expectedPairs = [
* ['a', 1],
* ['b', 2],
* ['c', 3],
* ] as const;
*
* assert.deepStrictEqual(pairs, expectedPairs);
* ```
*/
const zip = (array1, array2) =>
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
seq(Uint32.min(size(array1), size(array2))).map((i) =>
// Non-null assertion is safe here because `i` is always within bounds of both arrays up to the length of the shorter one.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
tp(array1[i], array2[i]));
/**
* Alias for `partition`.
*
* @see {@link partition}
*/
const chunk = partition;
export { chunk, concat, filter, filterNot, flat, flatMap, groupBy, map, partition, scan, toReversed, toSorted, toSortedBy, uniq, uniqBy, zip };
//# sourceMappingURL=array-utils-transformation.mjs.map