Skip to content

Commit 47d2fcd

Browse files
alexkvakmeskill
authored andcommitted
feat: add filterMap for array
1 parent 796ab9d commit 47d2fcd

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed

src/array/__tests__/filterMap.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import filterMap from '../filterMap';
2+
import map from '../map';
3+
import filter from '../filter';
4+
5+
describe('utils/array/filterMap', () => {
6+
it('should filter and map arrays', () => {
7+
expect(
8+
filterMap(
9+
() => true,
10+
(x) => x,
11+
[1]
12+
)
13+
).toEqual([1]);
14+
expect(
15+
filterMap(
16+
() => false,
17+
(x) => x,
18+
[1]
19+
)
20+
).toEqual([]);
21+
expect(
22+
filterMap(
23+
(x) => x > 2,
24+
(x) => x,
25+
[1, 2, 3, 4, 5]
26+
)
27+
).toEqual([3, 4, 5]);
28+
expect(
29+
filterMap(
30+
() => false,
31+
(x) => x,
32+
[1, 2, 3, 4, 5]
33+
)
34+
).toEqual([]);
35+
expect(
36+
filterMap(
37+
(n) => n % 2 === 0,
38+
(x) => x * 2,
39+
[1, 2, 3, 4]
40+
)
41+
).toEqual([4, 8]);
42+
});
43+
44+
it('is equivalent to filter + map', () => {
45+
const isEven = (n) => n % 2 === 0;
46+
const double = (x) => x * 2;
47+
const arr = [1, 2, 3, 4];
48+
49+
expect(filterMap(isEven, double, arr)).toEqual(map(double, filter(isEven, [1, 2, 3, 4])));
50+
});
51+
});

src/array/filterMap.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import curryN from '../function/curryN';
2+
import { ArrPred, MapFunc } from '../typings/types';
3+
4+
interface FilterMap {
5+
<T, R>(filterFn: ArrPred<T>, mapFn: MapFunc<T, R>, arr: ArrayLike<T>): R[];
6+
<T, R>(filterFn: ArrPred<T>, mapFn: MapFunc<T, R>): (arr: ArrayLike<T>) => R[];
7+
}
8+
9+
/**
10+
* This is shortcut for filter + map, but applied in one iteration.
11+
*
12+
* @param {Function} filterFn - filter function
13+
* @param {Function} mapFn - map function
14+
* @param {Array} arr
15+
* @return {Array}
16+
* @example
17+
*
18+
* var isEven = n => n % 2 === 0;
19+
* var double = x => x * 2;
20+
*
21+
* filterMap(isEven, double, [1, 2, 3, 4]); //=> [4, 8]
22+
*
23+
* // this is equivalent to
24+
* // map(double, filter(isEven, [1, 2, 3, 4]));
25+
*/
26+
export default curryN(3, <T, R>(filterFn: ArrPred<T>, mapFn: MapFunc<T, R>, arr: ArrayLike<T> = []) => {
27+
const result: R[] = [];
28+
29+
for (let i = 0; i < arr.length; i++) {
30+
if (filterFn(arr[i], i, arr)) {
31+
result.push(mapFn(arr[i], i, arr));
32+
}
33+
}
34+
35+
return result;
36+
}) as FilterMap;

src/array/map.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import curryN from '../function/curryN';
2-
3-
type MapFunc<T, R> = (item: T, i: number, arr: ArrayLike<T>) => R;
2+
import { MapFunc } from '../typings/types';
43

54
interface Map {
65
<T, R>(fn: MapFunc<T, R>, arr: ArrayLike<T>): R[];
@@ -22,7 +21,7 @@ interface Map {
2221
*/
2322
export default curryN(2, <T, R>(fn: MapFunc<T, R>, arr: ArrayLike<T> = []) => {
2423
const len = arr.length;
25-
const result = new Array(len);
24+
const result: R[] = new Array(len);
2625

2726
for (let i = 0; i < len; i++) {
2827
result[i] = fn(arr[i], i, arr);

src/typings/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export type ArrPred<T = any> = ArrBase<T, boolean>;
3232
export type ObjPred<K extends Prop, V> = ObjBase<K, V, boolean>;
3333
export type ObjPredBy<O> = ObjBaseBy<O, boolean>;
3434

35+
export type MapFunc<T, R> = (item: T, i: number, arr: ArrayLike<T>) => R;
36+
3537
export type Func<R = any> = (...args) => R;
3638
export type Func1<R = any> = (arg) => R;
3739

0 commit comments

Comments
 (0)