-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmapFilter.ts
41 lines (39 loc) · 1.32 KB
/
mapFilter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import empty from './empty.js';
import isEqual from './isEqual.js';
/**
* Transforms every value in the array using the given function and returns an array
* with the transformed values. If the function does not return a value, or returns
* undefined, then the value will be omitted from the final array.
*
* If every transformed value are the same than the original values and no values
* were filtered out, or if the original array is empty, the original array instance
* is returned instead of a new reference.
* @param array array of values to transform or filter
* @param fn function to determine the transformed value, or undefined
*/
function mapFilter<T, U>(array: T[], fn: (value: T, index: number) => U | undefined | void): U[] {
let altered = false;
let result: U[] | undefined;
array.forEach((value, index) => {
const transformed = fn(value, index);
if (typeof transformed === 'undefined') {
altered = true;
} else {
if (result == null) {
// First included item
result = [transformed];
} else {
// Latter included item
result.push(transformed);
}
if (!isEqual(transformed, value, 0)) {
altered = true;
}
}
});
if (!altered) {
return array as unknown[] as U[];
}
return result || empty;
}
export default mapFilter;