Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

distinctUntilChanged.ts 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { Operator } from '../Operator';
  2. import { Subscriber } from '../Subscriber';
  3. import { Observable } from '../Observable';
  4. import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
  5. /* tslint:disable:max-line-length */
  6. export function distinctUntilChanged<T>(compare?: (x: T, y: T) => boolean): MonoTypeOperatorFunction<T>;
  7. export function distinctUntilChanged<T, K>(compare: (x: K, y: K) => boolean, keySelector: (x: T) => K): MonoTypeOperatorFunction<T>;
  8. /* tslint:enable:max-line-length */
  9. /**
  10. * Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from the previous item.
  11. *
  12. * 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.
  13. *
  14. * If a comparator function is not provided, an equality check is used by default.
  15. *
  16. * ## Example
  17. * A simple example with numbers
  18. * ```ts
  19. * import { of } from 'rxjs';
  20. * import { distinctUntilChanged } from 'rxjs/operators';
  21. *
  22. * of(1, 1, 2, 2, 2, 1, 1, 2, 3, 3, 4).pipe(
  23. * distinctUntilChanged(),
  24. * )
  25. * .subscribe(x => console.log(x)); // 1, 2, 1, 2, 3, 4
  26. * ```
  27. *
  28. * An example using a compare function
  29. * ```typescript
  30. * import { of } from 'rxjs';
  31. * import { distinctUntilChanged } from 'rxjs/operators';
  32. *
  33. * interface Person {
  34. * age: number,
  35. * name: string
  36. * }
  37. *
  38. * of<Person>(
  39. * { age: 4, name: 'Foo'},
  40. * { age: 7, name: 'Bar'},
  41. * { age: 5, name: 'Foo'},
  42. * { age: 6, name: 'Foo'},
  43. * ).pipe(
  44. * distinctUntilChanged((p: Person, q: Person) => p.name === q.name),
  45. * )
  46. * .subscribe(x => console.log(x));
  47. *
  48. * // displays:
  49. * // { age: 4, name: 'Foo' }
  50. * // { age: 7, name: 'Bar' }
  51. * // { age: 5, name: 'Foo' }
  52. * ```
  53. *
  54. * @see {@link distinct}
  55. * @see {@link distinctUntilKeyChanged}
  56. *
  57. * @param {function} [compare] Optional comparison function called to test if an item is distinct from the previous item in the source.
  58. * @return {Observable} An Observable that emits items from the source Observable with distinct values.
  59. * @method distinctUntilChanged
  60. * @owner Observable
  61. */
  62. export function distinctUntilChanged<T, K>(compare?: (x: K, y: K) => boolean, keySelector?: (x: T) => K): MonoTypeOperatorFunction<T> {
  63. return (source: Observable<T>) => source.lift(new DistinctUntilChangedOperator<T, K>(compare, keySelector));
  64. }
  65. class DistinctUntilChangedOperator<T, K> implements Operator<T, T> {
  66. constructor(private compare: (x: K, y: K) => boolean,
  67. private keySelector: (x: T) => K) {
  68. }
  69. call(subscriber: Subscriber<T>, source: any): TeardownLogic {
  70. return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector));
  71. }
  72. }
  73. /**
  74. * We need this JSDoc comment for affecting ESDoc.
  75. * @ignore
  76. * @extends {Ignored}
  77. */
  78. class DistinctUntilChangedSubscriber<T, K> extends Subscriber<T> {
  79. private key: K;
  80. private hasKey: boolean = false;
  81. constructor(destination: Subscriber<T>,
  82. compare: (x: K, y: K) => boolean,
  83. private keySelector: (x: T) => K) {
  84. super(destination);
  85. if (typeof compare === 'function') {
  86. this.compare = compare;
  87. }
  88. }
  89. private compare(x: any, y: any): boolean {
  90. return x === y;
  91. }
  92. protected _next(value: T): void {
  93. let key: any;
  94. try {
  95. const { keySelector } = this;
  96. key = keySelector ? keySelector(value) : value;
  97. } catch (err) {
  98. return this.destination.error(err);
  99. }
  100. let result = false;
  101. if (this.hasKey) {
  102. try {
  103. const { compare } = this;
  104. result = compare(this.key, key);
  105. } catch (err) {
  106. return this.destination.error(err);
  107. }
  108. } else {
  109. this.hasKey = true;
  110. }
  111. if (!result) {
  112. this.key = key;
  113. this.destination.next(value);
  114. }
  115. }
  116. }