/
sort-map.ts
60 lines (59 loc) · 1.92 KB
/
sort-map.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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* @packageDocumentation
* @module Array
*/
import { OperatorFunction } from 'rxjs';
import { map } from 'rxjs/operators';
import { defaultSortFn } from '../utils/sort';
import { MapFn, SortFn } from '../types/generic-methods';
/**
* Returns an Observable that emits an array of sorted mapped values from a source array where values are mapped to
* type `K` using a [[MapFn]].
*
* @category Modify
*
* @typeParam T The input type of the source Array or Set
* @typeParam K The type of data in the emitted array
*
* @param mapFn The [[MapFn]] to map the value in the array
* @param sortFn Optional [[SortFn]] used to sort the array, if not provided the `defaultSortFn` is used.
*
* @example
* Returns a sorted array of binary values, sorting by number then converting to boolean
* ```ts
* const input = [5, 8, 2, 7, 1, 6];
* of(input).pipe(sortMap(value => value >= 5 ? true : false)).subscribe();
* ```
* Output: `[false, false, true, true, true, true]`
*
* @example
* Returns a sorted array of strings from an object, with [[SortFn]] and [[MapFn]]
* ```ts
* const sortFn = (a: any, b: any) => {
* if (a.index === b.index) return 0;
* return a.index < b.index ? -1 : 0
* }
*
* const mapFn = (item: any): string => item.label;
*
* const input = [
* { index: 5, label: 'Moo' }, { index:8, label: 'Baz' },
* { index: 2, label: 'Bar' }, { index: 7: label: 'Buzz' },
* { index: 1, label: 'Foo' } , { index: 6, label: 'Fizz' }
* ];
* of(input).pipe(sortMap(sortFn, mapFn)).subscribe();
* ```
* Output: `['Foo', 'Bar', 'Moo', 'Fizz', 'Buzz', 'Baz']`
*
* @returns Observable that emits an array of sorted mapped values
*/
export function sortMap<T extends unknown, K extends unknown>(
mapFn: MapFn<T, K>,
sortFn?: SortFn<T>,
): OperatorFunction<Iterable<T>, K[]> {
return (source) =>
source.pipe(
map((value) => [...value].sort(sortFn || defaultSortFn)),
map((value) => value.map(mapFn)),
);
}