From 9db141c35854514581f47a66c5ea29d0b8c90be8 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Tue, 25 Jul 2017 11:50:52 -0700 Subject: [PATCH] feat(distinctUntilKeyChanged): add higher-order lettable version of distinctUntilKeyChanged --- src/operator/distinctUntilKeyChanged.ts | 10 ++-- src/operators/distinctUntilKeyChanged.ts | 68 ++++++++++++++++++++++++ src/operators/index.ts | 1 + 3 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 src/operators/distinctUntilKeyChanged.ts diff --git a/src/operator/distinctUntilKeyChanged.ts b/src/operator/distinctUntilKeyChanged.ts index 147fc8f40f..62d8c3e7a5 100644 --- a/src/operator/distinctUntilKeyChanged.ts +++ b/src/operator/distinctUntilKeyChanged.ts @@ -1,5 +1,6 @@ -import { distinctUntilChanged } from './distinctUntilChanged'; + import { Observable } from '../Observable'; +import { distinctUntilKeyChanged as higherOrder } from '../operators'; /* tslint:disable:max-line-length */ export function distinctUntilKeyChanged(this: Observable, key: string): Observable; @@ -64,10 +65,5 @@ export function distinctUntilKeyChanged(this: Observable, key: string, * @owner Observable */ export function distinctUntilKeyChanged(this: Observable, key: string, compare?: (x: T, y: T) => boolean): Observable { - return distinctUntilChanged.call(this, function(x: T, y: T) { - if (compare) { - return compare(x[key], y[key]); - } - return x[key] === y[key]; - }); + return higherOrder(key, compare)(this); } diff --git a/src/operators/distinctUntilKeyChanged.ts b/src/operators/distinctUntilKeyChanged.ts new file mode 100644 index 0000000000..52ee021275 --- /dev/null +++ b/src/operators/distinctUntilKeyChanged.ts @@ -0,0 +1,68 @@ +import { distinctUntilChanged } from './distinctUntilChanged'; +import { MonoTypeOperatorFunction } from '../interfaces'; + +/* tslint:disable:max-line-length */ +export function distinctUntilKeyChanged(key: string): MonoTypeOperatorFunction; +export function distinctUntilKeyChanged(key: string, compare: (x: K, y: K) => boolean): MonoTypeOperatorFunction; +/* tslint:enable:max-line-length */ + +/** + * Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from the previous item, + * using a property accessed by using the key provided to check if the two items are distinct. + * + * If a comparator function is provided, then it will be called for each item to test for whether or not that value should be emitted. + * + * If a comparator function is not provided, an equality check is used by default. + * + * @example An example comparing the name of persons + * + * interface Person { + * age: number, + * name: string + * } + * + * Observable.of( + * { age: 4, name: 'Foo'}, + * { age: 7, name: 'Bar'}, + * { age: 5, name: 'Foo'}, + * { age: 6, name: 'Foo'}) + * .distinctUntilKeyChanged('name') + * .subscribe(x => console.log(x)); + * + * // displays: + * // { age: 4, name: 'Foo' } + * // { age: 7, name: 'Bar' } + * // { age: 5, name: 'Foo' } + * + * @example An example comparing the first letters of the name + * + * interface Person { + * age: number, + * name: string + * } + * + * Observable.of( + * { age: 4, name: 'Foo1'}, + * { age: 7, name: 'Bar'}, + * { age: 5, name: 'Foo2'}, + * { age: 6, name: 'Foo3'}) + * .distinctUntilKeyChanged('name', (x: string, y: string) => x.substring(0, 3) === y.substring(0, 3)) + * .subscribe(x => console.log(x)); + * + * // displays: + * // { age: 4, name: 'Foo1' } + * // { age: 7, name: 'Bar' } + * // { age: 5, name: 'Foo2' } + * + * @see {@link distinct} + * @see {@link distinctUntilChanged} + * + * @param {string} key String key for object property lookup on each item. + * @param {function} [compare] Optional comparison function called to test if an item is distinct from the previous item in the source. + * @return {Observable} An Observable that emits items from the source Observable with distinct values based on the key specified. + * @method distinctUntilKeyChanged + * @owner Observable + */ +export function distinctUntilKeyChanged(key: string, compare?: (x: T, y: T) => boolean): MonoTypeOperatorFunction { + return distinctUntilChanged((x: T, y: T) => compare ? compare(x[key], y[key]) : x[key] === y[key]); +} diff --git a/src/operators/index.ts b/src/operators/index.ts index 14a749df4b..10066ff50d 100644 --- a/src/operators/index.ts +++ b/src/operators/index.ts @@ -18,6 +18,7 @@ export { delay } from './delay'; export { delayWhen } from './delayWhen'; export { dematerialize } from './dematerialize'; export { distinctUntilChanged } from './distinctUntilChanged'; +export { distinctUntilKeyChanged } from './distinctUntilKeyChanged'; export { filter } from './filter'; export { ignoreElements } from './ignoreElements'; export { map } from './map';