Skip to content

Commit

Permalink
Add array chainWithIndex (#1256)
Browse files Browse the repository at this point in the history
  • Loading branch information
OliverJAsh authored Jun 29, 2020
1 parent 291c3bf commit 21f23d0
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 2 deletions.
11 changes: 11 additions & 0 deletions docs/modules/Array.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ Added in v2.0.0
- [unsafeInsertAt](#unsafeinsertat)
- [unsafeUpdateAt](#unsafeupdateat)
- [utils](#utils)
- [chainWithIndex](#chainwithindex)
- [chunksOf](#chunksof)
- [comprehension](#comprehension)
- [deleteAt](#deleteat)
Expand Down Expand Up @@ -1763,6 +1764,16 @@ Added in v2.0.0

# utils

## chainWithIndex

**Signature**

```ts
export declare const chainWithIndex: <A, B>(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
Expand Down
11 changes: 11 additions & 0 deletions docs/modules/ReadonlyArray.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -1556,6 +1557,16 @@ export interface Spanned<I, R> {

Added in v2.5.0

## chainWithIndex

**Signature**

```ts
export declare const chainWithIndex: <A, B>(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
Expand Down
7 changes: 7 additions & 0 deletions src/Array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,13 @@ export const apSecond: <B>(fb: Array<B>) => <A>(fa: Array<A>) => Array<B> = RA.a
*/
export const chain: <A, B>(f: (a: A) => Array<B>) => (ma: Array<A>) => Array<B> = RA.chain as any

/**
* @since 2.7.0
*/
export const chainWithIndex: <A, B>(
f: (index: number, a: A) => Array<B>
) => (ma: Array<A>) => Array<B> = 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.
Expand Down
16 changes: 14 additions & 2 deletions src/ReadonlyArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1431,13 +1431,16 @@ export const zero: Alternative1<URI>['zero'] = () => empty
const map_: Monad1<URI>['map'] = (fa, f) => fa.map((a) => f(a))
const mapWithIndex_: FunctorWithIndex1<URI, number>['mapWithIndex'] = (fa, f) => fa.map((a, i) => f(i, a))
const ap_: Monad1<URI>['ap'] = (fab, fa) => flatten(map_(fab, (f) => map_(fa, f)))
const chain_: Monad1<URI>['chain'] = (fa, f) => {
const chainWithIndex_: <A, B>(fa: ReadonlyArray<A>, f: (i: number, a: A) => ReadonlyArray<B>) => ReadonlyArray<B> = (
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
}
Expand All @@ -1453,6 +1456,8 @@ const chain_: Monad1<URI>['chain'] = (fa, f) => {
}
return out
}
const chain_: <A, B>(fa: ReadonlyArray<A>, f: (a: A) => ReadonlyArray<B>) => ReadonlyArray<B> = (fa, f) =>
chainWithIndex_(fa, (_index, a) => f(a))
const filterMap_: Filterable1<URI>['filterMap'] = (as, f) => filterMapWithIndex_(as, (_, a) => f(a))
const filter_: Filter1<URI> = <A>(as: ReadonlyArray<A>, predicate: Predicate<A>) => as.filter(predicate)
const partitionWithIndex_: PartitionWithIndex1<URI, number> = <A>(
Expand Down Expand Up @@ -1631,6 +1636,13 @@ export const apSecond = <B>(fb: ReadonlyArray<B>) => <A>(fa: ReadonlyArray<A>):
export const chain: <A, B>(f: (a: A) => ReadonlyArray<B>) => (ma: ReadonlyArray<A>) => ReadonlyArray<B> = (f) => (ma) =>
chain_(ma, f)

/**
* @since 2.7.0
*/
export const chainWithIndex: <A, B>(
f: (i: number, a: A) => ReadonlyArray<B>
) => (ma: ReadonlyArray<A>) => ReadonlyArray<B> = (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.
Expand Down
10 changes: 10 additions & 0 deletions test/Array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
10 changes: 10 additions & 0 deletions test/ReadonlyArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 21f23d0

Please sign in to comment.