aboutsummaryrefslogtreecommitdiffstats
path: root/node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts')
-rw-r--r--node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts182
1 files changed, 182 insertions, 0 deletions
diff --git a/node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts b/node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts
new file mode 100644
index 0000000..5db2f98
--- /dev/null
+++ b/node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts
@@ -0,0 +1,182 @@
+import { MonoTypeOperatorFunction } from '../types';
+import { identity } from '../util/identity';
+import { operate } from '../util/lift';
+import { createOperatorSubscriber } from './OperatorSubscriber';
+
+export function distinctUntilChanged<T>(comparator?: (previous: T, current: T) => boolean): MonoTypeOperatorFunction<T>;
+export function distinctUntilChanged<T, K>(
+ comparator: (previous: K, current: K) => boolean,
+ keySelector: (value: T) => K
+): MonoTypeOperatorFunction<T>;
+
+/**
+ * Returns a result {@link Observable} that emits all values pushed by the source observable if they
+ * are distinct in comparison to the last value the result observable emitted.
+ *
+ * When provided without parameters or with the first parameter (`{@link distinctUntilChanged#comparator comparator}`),
+ * it behaves like this:
+ *
+ * 1. It will always emit the first value from the source.
+ * 2. For all subsequent values pushed by the source, they will be compared to the previously emitted values
+ * using the provided `comparator` or an `===` equality check.
+ * 3. If the value pushed by the source is determined to be unequal by this check, that value is emitted and
+ * becomes the new "previously emitted value" internally.
+ *
+ * When the second parameter (`{@link distinctUntilChanged#keySelector keySelector}`) is provided, the behavior
+ * changes:
+ *
+ * 1. It will always emit the first value from the source.
+ * 2. The `keySelector` will be run against all values, including the first value.
+ * 3. For all values after the first, the selected key will be compared against the key selected from
+ * the previously emitted value using the `comparator`.
+ * 4. If the keys are determined to be unequal by this check, the value (not the key), is emitted
+ * and the selected key from that value is saved for future comparisons against other keys.
+ *
+ * ## Examples
+ *
+ * A very basic example with no `{@link distinctUntilChanged#comparator comparator}`. Note that `1` is emitted more than once,
+ * because it's distinct in comparison to the _previously emitted_ value,
+ * not in comparison to _all other emitted values_.
+ *
+ * ```ts
+ * import { of, distinctUntilChanged } from 'rxjs';
+ *
+ * of(1, 1, 1, 2, 2, 2, 1, 1, 3, 3)
+ * .pipe(distinctUntilChanged())
+ * .subscribe(console.log);
+ * // Logs: 1, 2, 1, 3
+ * ```
+ *
+ * With a `{@link distinctUntilChanged#comparator comparator}`, you can do custom comparisons. Let's say
+ * you only want to emit a value when all of its components have
+ * changed:
+ *
+ * ```ts
+ * import { of, distinctUntilChanged } from 'rxjs';
+ *
+ * const totallyDifferentBuilds$ = of(
+ * { engineVersion: '1.1.0', transmissionVersion: '1.2.0' },
+ * { engineVersion: '1.1.0', transmissionVersion: '1.4.0' },
+ * { engineVersion: '1.3.0', transmissionVersion: '1.4.0' },
+ * { engineVersion: '1.3.0', transmissionVersion: '1.5.0' },
+ * { engineVersion: '2.0.0', transmissionVersion: '1.5.0' }
+ * ).pipe(
+ * distinctUntilChanged((prev, curr) => {
+ * return (
+ * prev.engineVersion === curr.engineVersion ||
+ * prev.transmissionVersion === curr.transmissionVersion
+ * );
+ * })
+ * );
+ *
+ * totallyDifferentBuilds$.subscribe(console.log);
+ *
+ * // Logs:
+ * // { engineVersion: '1.1.0', transmissionVersion: '1.2.0' }
+ * // { engineVersion: '1.3.0', transmissionVersion: '1.4.0' }
+ * // { engineVersion: '2.0.0', transmissionVersion: '1.5.0' }
+ * ```
+ *
+ * You can also provide a custom `{@link distinctUntilChanged#comparator comparator}` to check that emitted
+ * changes are only in one direction. Let's say you only want to get
+ * the next record temperature:
+ *
+ * ```ts
+ * import { of, distinctUntilChanged } from 'rxjs';
+ *
+ * const temps$ = of(30, 31, 20, 34, 33, 29, 35, 20);
+ *
+ * const recordHighs$ = temps$.pipe(
+ * distinctUntilChanged((prevHigh, temp) => {
+ * // If the current temp is less than
+ * // or the same as the previous record,
+ * // the record hasn't changed.
+ * return temp <= prevHigh;
+ * })
+ * );
+ *
+ * recordHighs$.subscribe(console.log);
+ * // Logs: 30, 31, 34, 35
+ * ```
+ *
+ * Selecting update events only when the `updatedBy` field shows
+ * the account changed hands.
+ *
+ * ```ts
+ * import { of, distinctUntilChanged } from 'rxjs';
+ *
+ * // A stream of updates to a given account
+ * const accountUpdates$ = of(
+ * { updatedBy: 'blesh', data: [] },
+ * { updatedBy: 'blesh', data: [] },
+ * { updatedBy: 'ncjamieson', data: [] },
+ * { updatedBy: 'ncjamieson', data: [] },
+ * { updatedBy: 'blesh', data: [] }
+ * );
+ *
+ * // We only want the events where it changed hands
+ * const changedHands$ = accountUpdates$.pipe(
+ * distinctUntilChanged(undefined, update => update.updatedBy)
+ * );
+ *
+ * changedHands$.subscribe(console.log);
+ * // Logs:
+ * // { updatedBy: 'blesh', data: Array[0] }
+ * // { updatedBy: 'ncjamieson', data: Array[0] }
+ * // { updatedBy: 'blesh', data: Array[0] }
+ * ```
+ *
+ * @see {@link distinct}
+ * @see {@link distinctUntilKeyChanged}
+ *
+ * @param comparator A function used to compare the previous and current keys for
+ * equality. Defaults to a `===` check.
+ * @param keySelector Used to select a key value to be passed to the `comparator`.
+ *
+ * @return A function that returns an Observable that emits items from the
+ * source Observable with distinct values.
+ */
+export function distinctUntilChanged<T, K>(
+ comparator?: (previous: K, current: K) => boolean,
+ keySelector: (value: T) => K = identity as (value: T) => K
+): MonoTypeOperatorFunction<T> {
+ // We've been allowing `null` do be passed as the `compare`, so we can't do
+ // a default value for the parameter, because that will only work
+ // for `undefined`.
+ comparator = comparator ?? defaultCompare;
+
+ return operate((source, subscriber) => {
+ // The previous key, used to compare against keys selected
+ // from new arrivals to determine "distinctiveness".
+ let previousKey: K;
+ // Whether or not this is the first value we've gotten.
+ let first = true;
+
+ source.subscribe(
+ createOperatorSubscriber(subscriber, (value) => {
+ // We always call the key selector.
+ const currentKey = keySelector(value);
+
+ // If it's the first value, we always emit it.
+ // Otherwise, we compare this key to the previous key, and
+ // if the comparer returns false, we emit.
+ if (first || !comparator!(previousKey, currentKey)) {
+ // Update our state *before* we emit the value
+ // as emission can be the source of re-entrant code
+ // in functional libraries like this. We only really
+ // need to do this if it's the first value, or if the
+ // key we're tracking in previous needs to change.
+ first = false;
+ previousKey = currentKey;
+
+ // Emit the value!
+ subscriber.next(value);
+ }
+ })
+ );
+ });
+}
+
+function defaultCompare(a: any, b: any) {
+ return a === b;
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage