Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 1x 2x 2x 2x 8x 8x 6x 6x | import { identity, Mapper } from "@benneq/function";
/**
* Only emit values of an {@link Iterable} that have not been emitted yet.
*
* The values are by default compared by identity (`===`). An optional
* {@link Mapper} function can be used to map the values to a different
* representation for the comparison.
*
* @example
* Distinct by value
* ```ts
* const distinctByValue = distinct();
* const distinctValues = distinctByValue([1,2,1,3]);
* console.log(distinctValues); // [1,2,3]
* ```
*
* @example
* Distinct by `keyMapper` {@link Function}
* ```ts
* const distinctByValue = distinct(isEven);
* const distinctValues = distinctByValue([1,2,1,3]);
* console.log(distinctValues); // [1,2]
* ```
*
* @see {@link filter} for similar operations.
*
* @typeParam T - the {@link Iterable} value type
* @param keyMapper - a {@link Function} that maps an element into a key
* @returns an {@link Iterable} containing only unique values
*/
type Distinct = <T>(
keyMapper?: Mapper<T, unknown>
) => (iterable: Iterable<T>) => IterableIterator<T>;
export const distinct: Distinct = (keyMapper = identity) =>
function* (
iterable,
// internal variables:
seen = new Set<unknown>(),
key: unknown = undefined
) {
for (const value of iterable) {
key = keyMapper(value);
if (!seen.has(key)) {
seen.add(key);
yield value;
}
}
};
|