Skip to content

Commit 59f9cb2

Browse files
committed
1
1 parent 4c3781c commit 59f9cb2

7 files changed

Lines changed: 100 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
11.1.0
2+
3+
- Add `R.filterMap` - similar to Ruby `filter_map`
4+
5+
- Add index to `R.filter`/`R.reject` predicate signiture
6+
17
11.0.1
28

39
- Add missing JS change for `R.includes` and `R.excludes` methods in `11.0.0` release.

files/index.d.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ export function filter<T>(
486486
predicate: BooleanConstructor,
487487
): (list: T[]) => ExcludeFalsy<T>[];
488488
export function filter<T>(
489-
predicate: (value: T) => boolean,
489+
predicate: (value: T, index: number) => boolean,
490490
): (list: T[]) => T[];
491491

492492
/*
@@ -519,7 +519,7 @@ export function reject<T>(
519519
predicate: BooleanConstructor,
520520
): (list: T[]) => (null | undefined)[];
521521
export function reject<T>(
522-
predicate: (value: T) => boolean,
522+
predicate: (value: T, index: number) => boolean,
523523
): (list: T[]) => T[];
524524

525525
/*
@@ -995,12 +995,10 @@ Explanation: It returns the result of looping through `iterable` with `fn`.
995995
Example:
996996
997997
```
998-
const fn = x => x * 2
999-
1000-
const iterable = [1, 2]
1001-
const obj = {a: 1, b: 2}
1002-
1003-
const result = R.map(fn)(iterable),
998+
const result = R.pipe(
999+
[1, 2],
1000+
R.map(x => x * 2)
1001+
)
10041002
// => [2, 4]
10051003
```
10061004
@@ -1017,6 +1015,34 @@ export function map<T extends IterableContainer, U>(
10171015
fn: (value: T[number]) => U,
10181016
): (data: T) => Mapped<T, U>;
10191017

1018+
/*
1019+
Method: filterMap
1020+
1021+
Explanation: Same as `R.map` but it filters out `null/undefined` if returned from functor functions.
1022+
1023+
Example:
1024+
1025+
```
1026+
const result = R.pipe(
1027+
[1, 2, 3],
1028+
R.filterMap(x => x > 1 ? x : null)
1029+
)
1030+
// => [2, 3]
1031+
```
1032+
1033+
Categories: List
1034+
1035+
Notes: This function doesn't work with objects (use R.mapObject instead)
1036+
1037+
*/
1038+
// @SINGLE_MARKER
1039+
export function filterMap<T extends IterableContainer, U>(
1040+
fn: (value: T[number], index: number) => U,
1041+
): (data: T) => Mapped<T, ExcludeFalsy<U>>;
1042+
export function filterMap<T extends IterableContainer, U>(
1043+
fn: (value: T[number]) => U,
1044+
): (data: T) => Mapped<T, ExcludeFalsy<U>>;
1045+
10201046
/*
10211047
Method: mapObject
10221048

source/filter-spec.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,26 @@ const list = [1, 2, 3]
44

55
describe('R.filter with array', () => {
66
it('within pipe', () => {
7-
const _result = pipe(
7+
const result = pipe(
88
list,
99
filter(x => {
1010
x // $ExpectType number
1111
return x > 1
1212
}),
1313
)
14-
_result // $ExpectType number[]
14+
result // $ExpectType number[]
15+
})
16+
17+
it('with index', () => {
18+
const result = pipe(
19+
list,
20+
filter((x: number, i: number) => {
21+
x // $ExpectType number
22+
i // $ExpectType number
23+
return x > 1
24+
}),
25+
)
26+
result // $ExpectType number[]
1527
})
1628

1729
it('complex example', () => {
@@ -50,8 +62,8 @@ describe('R.filter with array', () => {
5062
const filterBar = (x: T): x is Bar => {
5163
return typeof (x as Bar).b === 'string'
5264
}
53-
const _result = pipe(testList, filter(filterBar))
54-
_result // $ExpectType Bar[]
65+
const result = pipe(testList, filter(filterBar))
66+
result // $ExpectType Bar[]
5567
})
5668

5769
it('narrowing type - readonly', () => {
@@ -66,14 +78,14 @@ describe('R.filter with array', () => {
6678
const filterBar = (x: T): x is Bar => {
6779
return typeof (x as Bar).b === 'string'
6880
}
69-
const _result = pipe(testList, filter(filterBar))
70-
_result // $ExpectType Bar[]
81+
const result = pipe(testList, filter(filterBar))
82+
result // $ExpectType Bar[]
7183
})
7284

7385
it('filtering NonNullable - list of objects', () => {
7486
const testList = [{ a: 1 }, { a: 2 }, false, { a: 3 }]
75-
const _result = pipe(testList, filter(Boolean))
76-
_result // $ExpectType { a: number; }[]
87+
const result = pipe(testList, filter(Boolean))
88+
result // $ExpectType { a: number; }[]
7789
})
7890

7991
it('filtering NonNullable - readonly', () => {

source/filterMap-spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { filterMap, pipe } from 'rambda'
2+
3+
const list = [1, 2, 3]
4+
5+
it('R.filterMap - within pipe', () => {
6+
const result = pipe(
7+
list,
8+
x => x,
9+
filterMap(x => {
10+
x // $ExpectType number
11+
return Math.random() > 0.5 ? String(x) : null
12+
}),
13+
filterMap(x => {
14+
x // $ExpectType string
15+
return Math.random() > 0.5 ? Number(x) : ''
16+
}),
17+
)
18+
result // $ExpectType number[]
19+
})

source/filterMap.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function filterMap(fn) {
2+
return list => mapFn(fn, list).filter(Boolean)
3+
}

source/filterMap.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { filterMap } from './filterMap.js'
2+
3+
const double = x => x > 1 ? x * 2 : null
4+
5+
it('happy', () => {
6+
expect(filterMap(double)([1, 2, 3])).toEqual([4, 6])
7+
})

source/reject-spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ describe('R.reject with array', () => {
1212
}),
1313
)
1414
result // $ExpectType number[]
15+
})
16+
it('with index', () => {
17+
const result = pipe(
18+
list,
19+
reject((x: number, i: number) => {
20+
x // $ExpectType number
21+
i // $ExpectType number
22+
return x > 1
23+
}),
24+
)
25+
result // $ExpectType number[]
1526
})
1627
it('narrowing type', () => {
1728
interface Foo {

0 commit comments

Comments
 (0)