UNPKG

veffect

Version:

powerful TypeScript validation library built on the robust foundation of Effect combining exceptional type safety, high performance, and developer experience. Taking inspiration from Effect's functional principles, VEffect delivers a balanced approach tha

1,402 lines (1,400 loc) 43.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sortBy = exports.sort = exports.some = exports.setNonEmptyLast = exports.setNonEmptyHead = exports.separate = exports.scanRight = exports.scan = exports.rotate = exports.reverse = exports.replicate = exports.replaceOption = exports.replace = exports.remove = exports.reduceRight = exports.reduce = exports.range = exports.prependAll = exports.prepend = exports.partitionMap = exports.partition = exports.of = exports.modifyOption = exports.modifyNonEmptyLast = exports.modifyNonEmptyHead = exports.modify = exports.min = exports.max = exports.matchRight = exports.matchLeft = exports.match = exports.mapAccum = exports.map = exports.makeBy = exports.make = exports.liftPredicate = exports.liftOption = exports.liftNullable = exports.liftEither = exports.length = exports.lastNonEmpty = exports.last = exports.join = exports.isNonEmptyReadonlyArray = exports.isNonEmptyArray = exports.isEmptyReadonlyArray = exports.isEmptyArray = exports.intersperse = exports.intersectionWith = exports.intersection = exports.insertAt = exports.initNonEmpty = exports.init = exports.headNonEmpty = exports.head = exports.groupWith = exports.groupBy = exports.group = exports.getSomes = exports.getRights = exports.getOrder = exports.getLefts = exports.getEquivalence = exports.get = exports.fromRecord = exports.fromOption = exports.fromNullable = exports.fromIterable = exports.forEach = exports.flatten = exports.flatMapNullable = exports.flatMap = exports.findLastIndex = exports.findLast = exports.findFirstIndex = exports.findFirst = exports.filterMapWhile = exports.filterMap = exports.filter = exports.extend = exports.every = exports.empty = exports.dropWhile = exports.dropRight = exports.drop = exports.differenceWith = exports.difference = exports.dedupeWith = exports.dedupeAdjacentWith = exports.dedupeAdjacent = exports.dedupe = exports.copy = exports.containsWith = exports.contains = exports.chunksOf = exports.chop = exports.cartesianWith = exports.cartesian = exports.appendAll = exports.append = void 0; exports.zipWith = exports.zip = exports.unzip = exports.unsafeGet = exports.unprepend = exports.unionWith = exports.union = exports.unfold = exports.unappend = exports.takeWhile = exports.takeRight = exports.take = exports.tailNonEmpty = exports.tail = exports.splitWhere = exports.splitNonEmptyAt = exports.splitAt = exports.split = exports.span = exports.sortWith = void 0; var E = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Either.js")); var Equal = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Equal.js")); var Equivalence = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Equivalence.js")); var _Function = /*#__PURE__*/require("./Function.js"); var readonlyArray = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./internal/readonlyArray.js")); var EffectIterable = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Iterable.js")); var O = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Option.js")); var Order = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Order.js")); var _Predicate = /*#__PURE__*/require("./Predicate.js"); var ReadonlyRecord = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./ReadonlyRecord.js")); var Tuple = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Tuple.js")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /** * This module provides utility functions for working with arrays in TypeScript. * * @since 2.0.0 */ /** * Builds a `NonEmptyArray` from an non-empty collection of elements. * * @category constructors * @since 2.0.0 */ const make = (...elements) => elements; /** * Return a `NonEmptyArray` of length `n` with element `i` initialized with `f(i)`. * * **Note**. `n` is normalized to an integer >= 1. * * @example * import { makeBy } from 'effect/ReadonlyArray' * * assert.deepStrictEqual(makeBy(5, n => n * 2), [0, 2, 4, 6, 8]) * * @category constructors * @since 2.0.0 */ exports.make = make; const makeBy = (n, f) => { const max = Math.max(1, Math.floor(n)); const out = [f(0)]; for (let i = 1; i < max; i++) { out.push(f(i)); } return out; }; /** * Return a `NonEmptyArray` containing a range of integers, including both endpoints. * * @example * import { range } from 'effect/ReadonlyArray' * * assert.deepStrictEqual(range(1, 3), [1, 2, 3]) * * @category constructors * @since 2.0.0 */ exports.makeBy = makeBy; const range = (start, end) => start <= end ? makeBy(end - start + 1, i => start + i) : [start]; /** * Return a `NonEmptyArray` containing a value repeated the specified number of times. * * **Note**. `n` is normalized to an integer >= 1. * * @example * import { replicate } from 'effect/ReadonlyArray' * * assert.deepStrictEqual(replicate("a", 3), ["a", "a", "a"]) * * @category constructors * @since 2.0.0 */ exports.range = range; const replicate = exports.replicate = /*#__PURE__*/(0, _Function.dual)(2, (a, n) => makeBy(n, () => a)); /** * Creates a new `Array` from an iterable collection of values. * * @category constructors * @since 2.0.0 */ const fromIterable = collection => Array.isArray(collection) ? collection : Array.from(collection); /** * Takes a record and returns an array of tuples containing its keys and values. * * @param self - The record to transform. * * @example * import { fromRecord } from "effect/ReadonlyArray" * * const x = { a: 1, b: 2, c: 3 } * assert.deepStrictEqual(fromRecord(x), [["a", 1], ["b", 2], ["c", 3]]) * * @category conversions * @since 2.0.0 */ exports.fromIterable = fromIterable; const fromRecord = exports.fromRecord = ReadonlyRecord.toEntries; /** * @category conversions * @since 2.0.0 */ const fromOption = exports.fromOption = O.toArray; /** * @category pattern matching * @since 2.0.0 */ const match = exports.match = /*#__PURE__*/(0, _Function.dual)(2, (self, { onEmpty, onNonEmpty }) => isNonEmptyReadonlyArray(self) ? onNonEmpty(self) : onEmpty()); /** * @category pattern matching * @since 2.0.0 */ const matchLeft = exports.matchLeft = /*#__PURE__*/(0, _Function.dual)(2, (self, { onEmpty, onNonEmpty }) => isNonEmptyReadonlyArray(self) ? onNonEmpty(headNonEmpty(self), tailNonEmpty(self)) : onEmpty()); /** * @category pattern matching * @since 2.0.0 */ const matchRight = exports.matchRight = /*#__PURE__*/(0, _Function.dual)(2, (self, { onEmpty, onNonEmpty }) => isNonEmptyReadonlyArray(self) ? onNonEmpty(initNonEmpty(self), lastNonEmpty(self)) : onEmpty()); /** * Prepend an element to the front of an `Iterable`, creating a new `NonEmptyArray`. * * @category concatenating * @since 2.0.0 */ const prepend = exports.prepend = /*#__PURE__*/(0, _Function.dual)(2, (self, head) => [head, ...self]); /** * Prepends the specified prefix array (or iterable) to the beginning of the specified array (or iterable). * If either array is non-empty, the result is also a non-empty array. * * @example * import * as ReadonlyArray from "effect/ReadonlyArray" * * assert.deepStrictEqual( * ReadonlyArray.prependAll([1, 2], ["a", "b"]), * ["a", "b", 1, 2] * ) * * @category concatenating * @since 2.0.0 */ const prependAll = exports.prependAll = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => fromIterable(that).concat(fromIterable(self))); /** * Append an element to the end of an `Iterable`, creating a new `NonEmptyArray`. * * @category concatenating * @since 2.0.0 */ const append = exports.append = /*#__PURE__*/(0, _Function.dual)(2, (self, last) => [...self, last]); /** * Concatenates two arrays (or iterables), combining their elements. * If either array is non-empty, the result is also a non-empty array. * * @category concatenating * @since 2.0.0 */ const appendAll = exports.appendAll = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => fromIterable(self).concat(fromIterable(that))); /** * Reduce an `Iterable` from the left, keeping all intermediate results instead of only the final result. * * @category folding * @since 2.0.0 */ const scan = exports.scan = /*#__PURE__*/(0, _Function.dual)(3, (self, b, f) => { const out = [b]; let i = 0; for (const a of self) { out[i + 1] = f(out[i], a); i++; } return out; }); /** * Reduce an `Iterable` from the right, keeping all intermediate results instead of only the final result. * * @category folding * @since 2.0.0 */ const scanRight = exports.scanRight = /*#__PURE__*/(0, _Function.dual)(3, (self, b, f) => { const input = fromIterable(self); const out = new Array(input.length + 1); out[input.length] = b; for (let i = input.length - 1; i >= 0; i--) { out[i] = f(out[i + 1], input[i]); } return out; }); /** * Determine if an `Array` is empty narrowing down the type to `[]`. * * @param self - The `Array` to check. * * @example * import { isEmptyArray } from "effect/ReadonlyArray" * * assert.deepStrictEqual(isEmptyArray([]), true); * assert.deepStrictEqual(isEmptyArray([1, 2, 3]), false); * * @category guards * @since 2.0.0 */ const isEmptyArray = self => self.length === 0; /** * Determine if a `ReadonlyArray` is empty narrowing down the type to `readonly []`. * * @param self - The `ReadonlyArray` to check. * * @example * import { isEmptyReadonlyArray } from "effect/ReadonlyArray" * * assert.deepStrictEqual(isEmptyReadonlyArray([]), true); * assert.deepStrictEqual(isEmptyReadonlyArray([1, 2, 3]), false); * * @category guards * @since 2.0.0 */ exports.isEmptyArray = isEmptyArray; const isEmptyReadonlyArray = exports.isEmptyReadonlyArray = isEmptyArray; /** * Determine if an `Array` is non empty narrowing down the type to `NonEmptyArray`. * * An `Array` is considered to be a `NonEmptyArray` if it contains at least one element. * * @param self - The `Array` to check. * * @example * import { isNonEmptyArray } from "effect/ReadonlyArray" * * assert.deepStrictEqual(isNonEmptyArray([]), false); * assert.deepStrictEqual(isNonEmptyArray([1, 2, 3]), true); * * @category guards * @since 2.0.0 */ const isNonEmptyArray = exports.isNonEmptyArray = readonlyArray.isNonEmptyArray; /** * Determine if a `ReadonlyArray` is non empty narrowing down the type to `NonEmptyReadonlyArray`. * * A `ReadonlyArray` is considered to be a `NonEmptyReadonlyArray` if it contains at least one element. * * @param self - The `ReadonlyArray` to check. * * @example * import { isNonEmptyReadonlyArray } from "effect/ReadonlyArray" * * assert.deepStrictEqual(isNonEmptyReadonlyArray([]), false); * assert.deepStrictEqual(isNonEmptyReadonlyArray([1, 2, 3]), true); * * @category guards * @since 2.0.0 */ const isNonEmptyReadonlyArray = exports.isNonEmptyReadonlyArray = readonlyArray.isNonEmptyArray; /** * Return the number of elements in a `ReadonlyArray`. * * @category getters * @since 2.0.0 */ const length = self => self.length; exports.length = length; const isOutOfBound = (i, as) => i < 0 || i >= as.length; const clamp = (i, as) => Math.floor(Math.min(Math.max(0, i), as.length)); /** * This function provides a safe way to read a value at a particular index from a `ReadonlyArray`. * * @category getters * @since 2.0.0 */ const get = exports.get = /*#__PURE__*/(0, _Function.dual)(2, (self, index) => { const i = Math.floor(index); return isOutOfBound(i, self) ? O.none() : O.some(self[i]); }); /** * Gets an element unsafely, will throw on out of bounds. * * @since 2.0.0 * @category unsafe */ const unsafeGet = exports.unsafeGet = /*#__PURE__*/(0, _Function.dual)(2, (self, index) => { const i = Math.floor(index); if (isOutOfBound(i, self)) { throw new Error(`Index ${i} out of bounds`); } return self[i]; }); /** * Return a tuple containing the first element, and a new `Array` of the remaining elements, if any. * * @category splitting * @since 2.0.0 */ const unprepend = self => [headNonEmpty(self), tailNonEmpty(self)]; /** * Return a tuple containing a copy of the `NonEmptyReadonlyArray` without its last element, and that last element. * * @category splitting * @since 2.0.0 */ exports.unprepend = unprepend; const unappend = self => [initNonEmpty(self), lastNonEmpty(self)]; /** * Get the first element of a `ReadonlyArray`, or `None` if the `ReadonlyArray` is empty. * * @category getters * @since 2.0.0 */ exports.unappend = unappend; const head = exports.head = /*#__PURE__*/get(0); /** * @category getters * @since 2.0.0 */ const headNonEmpty = exports.headNonEmpty = /*#__PURE__*/unsafeGet(0); /** * Get the last element in a `ReadonlyArray`, or `None` if the `ReadonlyArray` is empty. * * @category getters * @since 2.0.0 */ const last = self => isNonEmptyReadonlyArray(self) ? O.some(lastNonEmpty(self)) : O.none(); /** * @category getters * @since 2.0.0 */ exports.last = last; const lastNonEmpty = self => self[self.length - 1]; /** * Get all but the first element of an `Iterable`, creating a new `Array`, or `None` if the `Iterable` is empty. * * @category getters * @since 2.0.0 */ exports.lastNonEmpty = lastNonEmpty; const tail = self => { const input = fromIterable(self); return isNonEmptyReadonlyArray(input) ? O.some(tailNonEmpty(input)) : O.none(); }; /** * @category getters * @since 2.0.0 */ exports.tail = tail; const tailNonEmpty = self => self.slice(1); /** * Get all but the last element of an `Iterable`, creating a new `Array`, or `None` if the `Iterable` is empty. * * @category getters * @since 2.0.0 */ exports.tailNonEmpty = tailNonEmpty; const init = self => { const input = fromIterable(self); return isNonEmptyReadonlyArray(input) ? O.some(initNonEmpty(input)) : O.none(); }; /** * Get all but the last element of a non empty array, creating a new array. * * @category getters * @since 2.0.0 */ exports.init = init; const initNonEmpty = self => self.slice(0, -1); /** * Keep only a max number of elements from the start of an `Iterable`, creating a new `Array`. * * **Note**. `n` is normalized to a non negative integer. * * @category getters * @since 2.0.0 */ exports.initNonEmpty = initNonEmpty; const take = exports.take = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = fromIterable(self); return input.slice(0, clamp(n, input)); }); /** * Keep only a max number of elements from the end of an `Iterable`, creating a new `Array`. * * **Note**. `n` is normalized to a non negative integer. * * @category getters * @since 2.0.0 */ const takeRight = exports.takeRight = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = fromIterable(self); const i = clamp(n, input); return i === 0 ? [] : input.slice(-i); }); /** * Calculate the longest initial subarray for which all element satisfy the specified predicate, creating a new `Array`. * * @category getters * @since 2.0.0 */ const takeWhile = exports.takeWhile = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => { let i = 0; const out = []; for (const a of self) { if (!predicate(a, i)) { break; } out.push(a); i++; } return out; }); const spanIndex = (self, predicate) => { let i = 0; for (const a of self) { if (!predicate(a, i)) { break; } i++; } return i; }; /** * Split an `Iterable` into two parts: * * 1. the longest initial subarray for which all elements satisfy the specified predicate * 2. the remaining elements * * @category splitting * @since 2.0.0 */ const span = exports.span = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => splitAt(self, spanIndex(self, predicate))); /** * Drop a max number of elements from the start of an `Iterable`, creating a new `Array`. * * **Note**. `n` is normalized to a non negative integer. * * @category getters * @since 2.0.0 */ const drop = exports.drop = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = fromIterable(self); return input.slice(clamp(n, input), input.length); }); /** * Drop a max number of elements from the end of an `Iterable`, creating a new `Array`. * * **Note**. `n` is normalized to a non negative integer. * * @category getters * @since 2.0.0 */ const dropRight = exports.dropRight = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = fromIterable(self); return input.slice(0, input.length - clamp(n, input)); }); /** * Remove the longest initial subarray for which all element satisfy the specified predicate, creating a new `Array`. * * @category getters * @since 2.0.0 */ const dropWhile = exports.dropWhile = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => fromIterable(self).slice(spanIndex(self, predicate))); /** * Return the first index for which a predicate holds. * * @category elements * @since 2.0.0 */ const findFirstIndex = exports.findFirstIndex = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => { let i = 0; for (const a of self) { if (predicate(a, i)) { return O.some(i); } i++; } return O.none(); }); /** * Return the last index for which a predicate holds. * * @category elements * @since 2.0.0 */ const findLastIndex = exports.findLastIndex = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => { const input = fromIterable(self); for (let i = input.length - 1; i >= 0; i--) { if (predicate(input[i], i)) { return O.some(i); } } return O.none(); }); /** * Returns the first element that satisfies the specified * predicate, or `None` if no such element exists. * * @category elements * @since 2.0.0 */ const findFirst = exports.findFirst = EffectIterable.findFirst; /** * Find the last element for which a predicate holds. * * @category elements * @since 2.0.0 */ const findLast = exports.findLast = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => { const input = fromIterable(self); for (let i = input.length - 1; i >= 0; i--) { const a = input[i]; const o = f(a, i); if ((0, _Predicate.isBoolean)(o)) { if (o) { return O.some(a); } } else { if (O.isSome(o)) { return o; } } } return O.none(); }); /** * Insert an element at the specified index, creating a new `NonEmptyArray`, * or return `None` if the index is out of bounds. * * @since 2.0.0 */ const insertAt = exports.insertAt = /*#__PURE__*/(0, _Function.dual)(3, (self, i, b) => { const out = Array.from(self); // v--- `= self.length` is ok, it means inserting in last position if (i < 0 || i > out.length) { return O.none(); } out.splice(i, 0, b); return O.some(out); }); /** * Change the element at the specified index, creating a new `Array`, * or return a copy of the input if the index is out of bounds. * * @since 2.0.0 */ const replace = exports.replace = /*#__PURE__*/(0, _Function.dual)(3, (self, i, b) => modify(self, i, () => b)); /** * @since 2.0.0 */ const replaceOption = exports.replaceOption = /*#__PURE__*/(0, _Function.dual)(3, (self, i, b) => modifyOption(self, i, () => b)); /** * Apply a function to the element at the specified index, creating a new `Array`, * or return a copy of the input if the index is out of bounds. * * @since 2.0.0 */ const modify = exports.modify = /*#__PURE__*/(0, _Function.dual)(3, (self, i, f) => O.getOrElse(modifyOption(self, i, f), () => Array.from(self))); /** * Apply a function to the element at the specified index, creating a new `Array`, * or return `None` if the index is out of bounds. * * @since 2.0.0 */ const modifyOption = exports.modifyOption = /*#__PURE__*/(0, _Function.dual)(3, (self, i, f) => { const out = Array.from(self); if (isOutOfBound(i, out)) { return O.none(); } const next = f(out[i]); // @ts-expect-error out[i] = next; return O.some(out); }); /** * Delete the element at the specified index, creating a new `Array`, * or return a copy of the input if the index is out of bounds. * * @since 2.0.0 */ const remove = exports.remove = /*#__PURE__*/(0, _Function.dual)(2, (self, i) => { const out = Array.from(self); if (isOutOfBound(i, out)) { return out; } out.splice(i, 1); return out; }); /** * Reverse an `Iterable`, creating a new `Array`. * * @category elements * @since 2.0.0 */ const reverse = self => Array.from(self).reverse(); /** * Create a new array with elements sorted in increasing order based on the specified comparator. * If the input is a `NonEmptyReadonlyArray`, the output will also be a `NonEmptyReadonlyArray`. * * @category sorting * @since 2.0.0 */ exports.reverse = reverse; const sort = exports.sort = /*#__PURE__*/(0, _Function.dual)(2, (self, O) => { const out = Array.from(self); out.sort(O); return out; }); /** * @since 2.0.0 * @category elements */ const sortWith = exports.sortWith = /*#__PURE__*/(0, _Function.dual)(3, (self, f, order) => sort(self, Order.mapInput(order, f))); /** * Sort the elements of an `Iterable` in increasing order, where elements are compared * using first `orders[0]`, then `orders[1]`, etc... * * @category sorting * @since 2.0.0 */ const sortBy = (...orders) => { const sortByAll = sort(Order.combineAll(orders)); return self => { const input = fromIterable(self); if (isNonEmptyReadonlyArray(input)) { return sortByAll(input); } return []; }; }; /** * Takes two `Iterable`s and returns an `Array` of corresponding pairs. * If one input `Iterable` is short, excess elements of the * longer `Iterable` are discarded. * * @category zipping * @since 2.0.0 */ exports.sortBy = sortBy; const zip = exports.zip = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => zipWith(self, that, Tuple.make)); /** * Apply a function to pairs of elements at the same index in two `Iterable`s, collecting the results in a new `Array`. If one * input `Iterable` is short, excess elements of the longer `Iterable` are discarded. * * @category zipping * @since 2.0.0 */ const zipWith = exports.zipWith = /*#__PURE__*/(0, _Function.dual)(3, (self, that, f) => { const as = fromIterable(self); const bs = fromIterable(that); if (isNonEmptyReadonlyArray(as) && isNonEmptyReadonlyArray(bs)) { const out = [f(headNonEmpty(as), headNonEmpty(bs))]; const len = Math.min(as.length, bs.length); for (let i = 1; i < len; i++) { out[i] = f(as[i], bs[i]); } return out; } return []; }); /** * This function is the inverse of `zip`. Takes an `Iterable` of pairs and return two corresponding `Array`s. * * @since 2.0.0 */ const unzip = self => { const input = fromIterable(self); if (isNonEmptyReadonlyArray(input)) { const fa = [input[0][0]]; const fb = [input[0][1]]; for (let i = 1; i < input.length; i++) { fa[i] = input[i][0]; fb[i] = input[i][1]; } return [fa, fb]; } return [[], []]; }; /** * Places an element in between members of an `Iterable`. * If the input is a non-empty array, the result is also a non-empty array. * * @since 2.0.0 */ exports.unzip = unzip; const intersperse = exports.intersperse = /*#__PURE__*/(0, _Function.dual)(2, (self, middle) => { const input = fromIterable(self); if (isNonEmptyReadonlyArray(input)) { const out = [headNonEmpty(input)]; const tail = tailNonEmpty(input); for (let i = 0; i < tail.length; i++) { if (i < tail.length) { out.push(middle); } out.push(tail[i]); } return out; } return []; }); /** * Apply a function to the head, creating a new `NonEmptyReadonlyArray`. * * @since 2.0.0 */ const modifyNonEmptyHead = exports.modifyNonEmptyHead = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => [f(headNonEmpty(self)), ...tailNonEmpty(self)]); /** * Change the head, creating a new `NonEmptyReadonlyArray`. * * @since 2.0.0 */ const setNonEmptyHead = exports.setNonEmptyHead = /*#__PURE__*/(0, _Function.dual)(2, (self, b) => modifyNonEmptyHead(self, () => b)); /** * Apply a function to the last element, creating a new `NonEmptyReadonlyArray`. * * @since 2.0.0 */ const modifyNonEmptyLast = exports.modifyNonEmptyLast = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => append(initNonEmpty(self), f(lastNonEmpty(self)))); /** * Change the last element, creating a new `NonEmptyReadonlyArray`. * * @since 2.0.0 */ const setNonEmptyLast = exports.setNonEmptyLast = /*#__PURE__*/(0, _Function.dual)(2, (self, b) => modifyNonEmptyLast(self, () => b)); /** * Rotate an `Iterable` by `n` steps. * If the input is a non-empty array, the result is also a non-empty array. * * @since 2.0.0 */ const rotate = exports.rotate = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = fromIterable(self); if (isNonEmptyReadonlyArray(input)) { const len = input.length; const m = Math.round(n) % len; if (isOutOfBound(Math.abs(m), input) || m === 0) { return copy(input); } if (m < 0) { const [f, s] = splitNonEmptyAt(input, -m); return appendAll(s, f); } else { return rotate(self, m - len); } } return []; }); /** * Returns a function that checks if a `ReadonlyArray` contains a given value using a provided `isEquivalent` function. * * @category elements * @since 2.0.0 */ const containsWith = isEquivalent => (0, _Function.dual)(2, (self, a) => { for (const i of self) { if (isEquivalent(a, i)) { return true; } } return false; }); exports.containsWith = containsWith; const _equivalence = /*#__PURE__*/Equal.equivalence(); /** * Returns a function that checks if a `ReadonlyArray` contains a given value using the default `Equivalence`. * * @category elements * @since 2.0.0 */ const contains = exports.contains = /*#__PURE__*/containsWith(_equivalence); /** * A useful recursion pattern for processing an `Iterable` to produce a new `Array`, often used for "chopping" up the input * `Iterable`. Typically chop is called with some function that will consume an initial prefix of the `Iterable` and produce a * value and the rest of the `Array`. * * @since 2.0.0 */ const chop = exports.chop = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => { const input = fromIterable(self); if (isNonEmptyReadonlyArray(input)) { const [b, rest] = f(input); const out = [b]; let next = rest; while (readonlyArray.isNonEmptyArray(next)) { const [b, rest] = f(next); out.push(b); next = rest; } return out; } return []; }); /** * Splits an `Iterable` into two segments, with the first segment containing a maximum of `n` elements. * The value of `n` can be `0`. * * @category splitting * @since 2.0.0 */ const splitAt = exports.splitAt = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = Array.from(self); const _n = Math.floor(n); if (isNonEmptyReadonlyArray(input)) { if (_n >= 1) { return splitNonEmptyAt(input, _n); } return [[], input]; } return [input, []]; }); /** * Splits a `NonEmptyReadonlyArray` into two segments, with the first segment containing a maximum of `n` elements. * The value of `n` must be `>= 1`. * * @category splitting * @since 2.0.0 */ const splitNonEmptyAt = exports.splitNonEmptyAt = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const _n = Math.max(1, Math.floor(n)); return _n >= self.length ? [copy(self), []] : [prepend(self.slice(1, _n), headNonEmpty(self)), self.slice(_n)]; }); /** * Splits this iterable into `n` equally sized arrays. * * @since 2.0.0 * @category splitting */ const split = exports.split = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = fromIterable(self); return chunksOf(input, Math.ceil(input.length / Math.floor(n))); }); /** * Splits this iterable on the first element that matches this predicate. * Returns a tuple containing two arrays: the first one is before the match, and the second one is from the match onward. * * @category splitting * @since 2.0.0 */ const splitWhere = exports.splitWhere = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => span(self, (a, i) => !predicate(a, i))); /** * @since 2.0.0 */ const copy = self => self.slice(); /** * Splits an `Iterable` into length-`n` pieces. The last piece will be shorter if `n` does not evenly divide the length of * the `Iterable`. Note that `chunksOf(n)([])` is `[]`, not `[[]]`. This is intentional, and is consistent with a recursive * definition of `chunksOf`; it satisfies the property that * * ```ts * chunksOf(n)(xs).concat(chunksOf(n)(ys)) == chunksOf(n)(xs.concat(ys))) * ``` * * whenever `n` evenly divides the length of `self`. * * @category splitting * @since 2.0.0 */ exports.copy = copy; const chunksOf = exports.chunksOf = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => { const input = fromIterable(self); if (isNonEmptyReadonlyArray(input)) { return chop(input, splitNonEmptyAt(n)); } return []; }); /** * Group equal, consecutive elements of a `NonEmptyReadonlyArray` into `NonEmptyArray`s using the provided `isEquivalent` function. * * @category grouping * @since 2.0.0 */ const groupWith = exports.groupWith = /*#__PURE__*/(0, _Function.dual)(2, (self, isEquivalent) => chop(self, as => { const h = headNonEmpty(as); const out = [h]; let i = 1; for (; i < as.length; i++) { const a = as[i]; if (isEquivalent(a, h)) { out.push(a); } else { break; } } return [out, as.slice(i)]; })); /** * Group equal, consecutive elements of a `NonEmptyReadonlyArray` into `NonEmptyArray`s. * * @category grouping * @since 2.0.0 */ const group = exports.group = /*#__PURE__*/groupWith( /*#__PURE__*/Equal.equivalence()); /** * Splits an `Iterable` into sub-non-empty-arrays stored in an object, based on the result of calling a `string`-returning * function on each element, and grouping the results according to values returned * * @category grouping * @since 2.0.0 */ const groupBy = exports.groupBy = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => { const out = {}; for (const a of self) { const k = f(a); if (Object.prototype.hasOwnProperty.call(out, k)) { out[k].push(a); } else { out[k] = [a]; } } return out; }); /** * @since 2.0.0 */ const unionWith = exports.unionWith = /*#__PURE__*/(0, _Function.dual)(3, (self, that, isEquivalent) => { const a = fromIterable(self); const b = fromIterable(that); if (isNonEmptyReadonlyArray(a)) { if (isNonEmptyReadonlyArray(b)) { const dedupe = dedupeWith(isEquivalent); return dedupe(appendAll(a, b)); } return a; } return b; }); /** * @since 2.0.0 */ const union = exports.union = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => unionWith(self, that, _equivalence)); /** * Creates an `Array` of unique values that are included in all given `Iterable`s using the provided `isEquivalent` function. * The order and references of result values are determined by the first `Iterable`. * * @since 2.0.0 */ const intersectionWith = isEquivalent => { const has = containsWith(isEquivalent); return (0, _Function.dual)(2, (self, that) => fromIterable(self).filter(a => has(that, a))); }; /** * Creates an `Array` of unique values that are included in all given `Iterable`s. * The order and references of result values are determined by the first `Iterable`. * * @since 2.0.0 */ exports.intersectionWith = intersectionWith; const intersection = exports.intersection = /*#__PURE__*/intersectionWith(_equivalence); /** * Creates a `Array` of values not included in the other given `Iterable` using the provided `isEquivalent` function. * The order and references of result values are determined by the first `Iterable`. * * @since 2.0.0 */ const differenceWith = isEquivalent => { const has = containsWith(isEquivalent); return (0, _Function.dual)(2, (self, that) => fromIterable(self).filter(a => !has(that, a))); }; /** * Creates a `Array` of values not included in the other given `Iterable`. * The order and references of result values are determined by the first `Iterable`. * * @since 2.0.0 */ exports.differenceWith = differenceWith; const difference = exports.difference = /*#__PURE__*/differenceWith(_equivalence); /** * @category constructors * @since 2.0.0 */ const empty = () => []; /** * Constructs a new `NonEmptyArray<A>` from the specified value. * * @category constructors * @since 2.0.0 */ exports.empty = empty; const of = a => [a]; /** * @category mapping * @since 2.0.0 */ exports.of = of; const map = exports.map = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => self.map(f)); /** * Applies a function to each element in an array and returns a new array containing the concatenated mapped elements. * * @category sequencing * @since 2.0.0 */ const flatMap = exports.flatMap = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => { if (isEmptyReadonlyArray(self)) { return []; } const out = []; for (let i = 0; i < self.length; i++) { const inner = f(self[i], i); for (let j = 0; j < inner.length; j++) { out.push(inner[j]); } } return out; }); /** * Flattens an array of arrays into a single array by concatenating all arrays. * * @category sequencing * @since 2.0.0 */ const flatten = exports.flatten = /*#__PURE__*/flatMap(_Function.identity); /** * @category filtering * @since 2.0.0 */ const filterMap = exports.filterMap = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => { const as = fromIterable(self); const out = []; for (let i = 0; i < as.length; i++) { const o = f(as[i], i); if (O.isSome(o)) { out.push(o.value); } } return out; }); /** * Transforms all elements of the `readonlyArray` for as long as the specified function returns some value * * @category filtering * @since 2.0.0 */ const filterMapWhile = exports.filterMapWhile = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => { let i = 0; const out = []; for (const a of self) { const b = f(a, i); if (O.isSome(b)) { out.push(b.value); } else { break; } i++; } return out; }); /** * @category filtering * @since 2.0.0 */ const partitionMap = exports.partitionMap = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => { const left = []; const right = []; const as = fromIterable(self); for (let i = 0; i < as.length; i++) { const e = f(as[i], i); if (E.isLeft(e)) { left.push(e.left); } else { right.push(e.right); } } return [left, right]; }); /** * Retrieves the `Some` values from an `Iterable` of `Option`s, collecting them into an array. * * @example * import { getSomes } from "effect/ReadonlyArray" * import { some, none } from "effect/Option" * * assert.deepStrictEqual( * getSomes([some(1), none(), some(2)]), * [1, 2] * ) * * @category filtering * @since 2.0.0 */ const getSomes = exports.getSomes = /*#__PURE__*/filterMap(_Function.identity); /** * Retrieves the `Left` values from an `Iterable` of `Either`s, collecting them into an array. * * @example * import { getLefts } from "effect/ReadonlyArray" * import { right, left } from "effect/Either" * * assert.deepStrictEqual( * getLefts([right(1), left("err"), right(2)]), * ["err"] * ) * * @category filtering * @since 2.0.0 */ const getLefts = self => { const out = []; for (const a of self) { if (E.isLeft(a)) { out.push(a.left); } } return out; }; /** * Retrieves the `Right` values from an `Iterable` of `Either`s, collecting them into an array. * * @example * import { getRights } from "effect/ReadonlyArray" * import { right, left } from "effect/Either" * * assert.deepStrictEqual( * getRights([right(1), left("err"), right(2)]), * [1, 2] * ) * * @category filtering * @since 2.0.0 */ exports.getLefts = getLefts; const getRights = self => { const out = []; for (const a of self) { if (E.isRight(a)) { out.push(a.right); } } return out; }; /** * @category filtering * @since 2.0.0 */ exports.getRights = getRights; const filter = exports.filter = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => { const as = fromIterable(self); const out = []; for (let i = 0; i < as.length; i++) { if (predicate(as[i], i)) { out.push(as[i]); } } return out; }); /** * Separate elements based on a predicate that also exposes the index of the element. * * @category filtering * @since 2.0.0 */ const partition = exports.partition = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => { const left = []; const right = []; const as = fromIterable(self); for (let i = 0; i < as.length; i++) { if (predicate(as[i], i)) { right.push(as[i]); } else { left.push(as[i]); } } return [left, right]; }); /** * @category filtering * @since 2.0.0 */ const separate = exports.separate = /*#__PURE__*/partitionMap(_Function.identity); /** * @category folding * @since 2.0.0 */ const reduce = exports.reduce = /*#__PURE__*/(0, _Function.dual)(3, (self, b, f) => fromIterable(self).reduce((b, a, i) => f(b, a, i), b)); /** * @category folding * @since 2.0.0 */ const reduceRight = exports.reduceRight = /*#__PURE__*/(0, _Function.dual)(3, (self, b, f) => fromIterable(self).reduceRight((b, a, i) => f(b, a, i), b)); /** * @category lifting * @since 2.0.0 */ const liftPredicate = predicate => b => predicate(b) ? [b] : []; /** * @category lifting * @since 2.0.0 */ exports.liftPredicate = liftPredicate; const liftOption = f => (...a) => fromOption(f(...a)); /** * @category conversions * @since 2.0.0 */ exports.liftOption = liftOption; const fromNullable = a => a == null ? empty() : [a]; /** * @category lifting * @since 2.0.0 */ exports.fromNullable = fromNullable; const liftNullable = f => (...a) => fromNullable(f(...a)); /** * @category sequencing * @since 2.0.0 */ exports.liftNullable = liftNullable; const flatMapNullable = exports.flatMapNullable = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => isNonEmptyReadonlyArray(self) ? fromNullable(f(headNonEmpty(self))) : empty()); /** * @category lifting * @since 2.0.0 */ const liftEither = f => (...a) => { const e = f(...a); return E.isLeft(e) ? [] : [e.right]; }; /** * Check if a predicate holds true for every `ReadonlyArray` element. * * @category elements * @since 2.0.0 */ exports.liftEither = liftEither; const every = exports.every = /*#__PURE__*/(0, _Function.dual)(2, (self, refinement) => self.every(refinement)); /** * Check if a predicate holds true for some `ReadonlyArray` element. * * @category elements * @since 2.0.0 */ const some = exports.some = /*#__PURE__*/(0, _Function.dual)(2, (self, predicate) => self.some(predicate)); /** * @since 2.0.0 */ const extend = exports.extend = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => self.map((_, i, as) => f(as.slice(i)))); /** * @since 2.0.0 */ const min = exports.min = /*#__PURE__*/(0, _Function.dual)(2, (self, O) => self.reduce(Order.min(O))); /** * @since 2.0.0 */ const max = exports.max = /*#__PURE__*/(0, _Function.dual)(2, (self, O) => self.reduce(Order.max(O))); /** * @category constructors * @since 2.0.0 */ const unfold = (b, f) => { const out = []; let next = b; let o; while (O.isSome(o = f(next))) { const [a, b] = o.value; out.push(a); next = b; } return out; }; /** * This function creates and returns a new `Order` for an array of values based on a given `Order` for the elements of the array. * The returned `Order` compares two arrays by applying the given `Order` to each element in the arrays. * If all elements are equal, the arrays are then compared based on their length. * It is useful when you need to compare two arrays of the same type and you have a specific way of comparing each element of the array. * * @category instances * @since 2.0.0 */ exports.unfold = unfold; const getOrder = exports.getOrder = Order.array; /** * @category instances * @since 2.0.0 */ const getEquivalence = exports.getEquivalence = Equivalence.array; /** * Iterate over the `Iterable` applying `f`. * * @since 2.0.0 */ const forEach = exports.forEach = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => fromIterable(self).forEach((a, i) => f(a, i))); /** * Remove duplicates from an `Iterable` using the provided `isEquivalent` function, * preserving the order of the first occurrence of each element. * * @since 2.0.0 */ const dedupeWith = exports.dedupeWith = /*#__PURE__*/(0, _Function.dual)(2, (self, isEquivalent) => { const input = fromIterable(self); if (isNonEmptyReadonlyArray(input)) { const out = [headNonEmpty(input)]; const rest = tailNonEmpty(input); for (const r of rest) { if (out.every(a => !isEquivalent(r, a))) { out.push(r); } } return out; } return []; }); /** * Remove duplicates from an `Iterable`, preserving the order of the first occurrence of each element. * The equivalence used to compare elements is provided by `Equal.equivalence()` from the `Equal` module. * * @since 2.0.0 */ const dedupe = self => dedupeWith(self, Equal.equivalence()); /** * Deduplicates adjacent elements that are identical using the provided `isEquivalent` function. * * @since 2.0.0 */ exports.dedupe = dedupe; const dedupeAdjacentWith = exports.dedupeAdjacentWith = /*#__PURE__*/(0, _Function.dual)(2, (self, isEquivalent) => { const out = []; let lastA = O.none(); for (const a of self) { if (O.isNone(lastA) || !isEquivalent(a, lastA.value)) { out.push(a); lastA = O.some(a); } } return out; }); /** * Deduplicates adjacent elements that are identical. * * @since 2.0.0 */ const dedupeAdjacent = exports.dedupeAdjacent = /*#__PURE__*/dedupeAdjacentWith( /*#__PURE__*/Equal.equivalence()); /** * Joins the elements together with "sep" in the middle. * * @since 2.0.0 * @category folding */ const join = exports.join = /*#__PURE__*/(0, _Function.dual)(2, (self, sep) => fromIterable(self).join(sep)); /** * Statefully maps over the chunk, producing new elements of type `B`. * * @since 2.0.0 * @category folding */ const mapAccum = exports.mapAccum = /*#__PURE__*/(0, _Function.dual)(3, (self, s, f) => { let i = 0; let s1 = s; const out = []; for (const a of self) { const r = f(s1, a, i); s1 = r[0]; out.push(r[1]); i++; } return [s1, out]; }); /** * Zips this chunk crosswise with the specified chunk using the specified combiner. * * @since 2.0.0 * @category elements */ const cartesianWith = exports.cartesianWith = /*#__PURE__*/(0, _Function.dual)(3, (self, that, f) => flatMap(self, a => map(that, b => f(a, b)))); /** * Zips this chunk crosswise with the specified chunk. * * @since 2.0.0 * @category elements */ const cartesian = exports.cartesian = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => cartesianWith(self, that, (a, b) => [a, b])); //# sourceMappingURL=ReadonlyArray.js.map