diff --git a/docs/modules/Array.ts.md b/docs/modules/Array.ts.md index bf6845c49..3c527b565 100644 --- a/docs/modules/Array.ts.md +++ b/docs/modules/Array.ts.md @@ -135,6 +135,7 @@ Added in v2.0.0 - [unsafeInsertAt](#unsafeinsertat) - [unsafeUpdateAt](#unsafeupdateat) - [utils](#utils) + - [chainWithIndex](#chainwithindex) - [chunksOf](#chunksof) - [comprehension](#comprehension) - [deleteAt](#deleteat) @@ -1763,6 +1764,16 @@ Added in v2.0.0 # utils +## chainWithIndex + +**Signature** + +```ts +export declare const chainWithIndex: (f: (index: number, a: A) => B[]) => (ma: A[]) => B[] +``` + +Added in v2.7.0 + ## chunksOf Splits an array into length-`n` pieces. The last piece will be shorter if `n` does not evenly divide the length of diff --git a/docs/modules/ReadonlyArray.ts.md b/docs/modules/ReadonlyArray.ts.md index 09ed2578d..ce884c31f 100644 --- a/docs/modules/ReadonlyArray.ts.md +++ b/docs/modules/ReadonlyArray.ts.md @@ -127,6 +127,7 @@ Added in v2.5.0 - [unsafeUpdateAt](#unsafeupdateat) - [utils](#utils) - [Spanned (interface)](#spanned-interface) + - [chainWithIndex](#chainwithindex) - [chunksOf](#chunksof) - [comprehension](#comprehension) - [deleteAt](#deleteat) @@ -1556,6 +1557,16 @@ export interface Spanned { Added in v2.5.0 +## chainWithIndex + +**Signature** + +```ts +export declare const chainWithIndex: (f: (i: number, a: A) => readonly B[]) => (ma: readonly A[]) => readonly B[] +``` + +Added in v2.7.0 + ## chunksOf Splits an array into length-`n` pieces. The last piece will be shorter if `n` does not evenly divide the length of diff --git a/src/Array.ts b/src/Array.ts index fb04f0ebf..7796caf6f 100644 --- a/src/Array.ts +++ b/src/Array.ts @@ -1054,6 +1054,13 @@ export const apSecond: (fb: Array) => (fa: Array) => Array = RA.a */ export const chain: (f: (a: A) => Array) => (ma: Array) => Array = RA.chain as any +/** + * @since 2.7.0 + */ +export const chainWithIndex: ( + f: (index: number, a: A) => Array +) => (ma: Array) => Array = RA.chainWithIndex as any + /** * Composes computations in sequence, using the return value of one computation to determine the next computation and * keeping only the result of the first. diff --git a/src/ReadonlyArray.ts b/src/ReadonlyArray.ts index db6545050..500227e73 100644 --- a/src/ReadonlyArray.ts +++ b/src/ReadonlyArray.ts @@ -1431,13 +1431,16 @@ export const zero: Alternative1['zero'] = () => empty const map_: Monad1['map'] = (fa, f) => fa.map((a) => f(a)) const mapWithIndex_: FunctorWithIndex1['mapWithIndex'] = (fa, f) => fa.map((a, i) => f(i, a)) const ap_: Monad1['ap'] = (fab, fa) => flatten(map_(fab, (f) => map_(fa, f))) -const chain_: Monad1['chain'] = (fa, f) => { +const chainWithIndex_: (fa: ReadonlyArray, f: (i: number, a: A) => ReadonlyArray) => ReadonlyArray = ( + fa, + f +) => { let outLen = 0 const l = fa.length const temp = new Array(l) for (let i = 0; i < l; i++) { const e = fa[i] - const arr = f(e) + const arr = f(i, e) outLen += arr.length temp[i] = arr } @@ -1453,6 +1456,8 @@ const chain_: Monad1['chain'] = (fa, f) => { } return out } +const chain_: (fa: ReadonlyArray, f: (a: A) => ReadonlyArray) => ReadonlyArray = (fa, f) => + chainWithIndex_(fa, (_index, a) => f(a)) const filterMap_: Filterable1['filterMap'] = (as, f) => filterMapWithIndex_(as, (_, a) => f(a)) const filter_: Filter1 = (as: ReadonlyArray, predicate: Predicate) => as.filter(predicate) const partitionWithIndex_: PartitionWithIndex1 = ( @@ -1631,6 +1636,13 @@ export const apSecond = (fb: ReadonlyArray) => (fa: ReadonlyArray): export const chain: (f: (a: A) => ReadonlyArray) => (ma: ReadonlyArray) => ReadonlyArray = (f) => (ma) => chain_(ma, f) +/** + * @since 2.7.0 + */ +export const chainWithIndex: ( + f: (i: number, a: A) => ReadonlyArray +) => (ma: ReadonlyArray) => ReadonlyArray = (f) => (ma) => chainWithIndex_(ma, f) + /** * Composes computations in sequence, using the return value of one computation to determine the next computation and * keeping only the result of the first. diff --git a/test/Array.ts b/test/Array.ts index bc8103dae..6fb932a80 100644 --- a/test/Array.ts +++ b/test/Array.ts @@ -131,6 +131,16 @@ describe('Array', () => { ) }) + it('chainWithIndex', () => { + assert.deepStrictEqual( + pipe( + [1, 2, 3], + _.chainWithIndex((i, n) => [n + i]) + ), + [1, 3, 5] + ) + }) + it('chainFirst', () => { assert.deepStrictEqual( pipe( diff --git a/test/ReadonlyArray.ts b/test/ReadonlyArray.ts index aa90752cb..4a56ebe49 100644 --- a/test/ReadonlyArray.ts +++ b/test/ReadonlyArray.ts @@ -127,6 +127,16 @@ describe('ReadonlyArray', () => { ) }) + it('chainWithIndex', () => { + assert.deepStrictEqual( + pipe( + [1, 2, 3], + _.chainWithIndex((i, n) => [n + i]) + ), + [1, 3, 5] + ) + }) + it('chainFirst', () => { assert.deepStrictEqual( pipe(