we can use for the distinctUntilChanged operator. In this case, we still receive the duplicate value because the operator compares by reference by default. The two 'Ella' strings are mapped to Name data structures by the map operator, each a new object reference so they both pass the distinctUntilChanged operator. import { delay, distinctUntilChanged, filter, from, map, Observable, Subscription, tap } from 'rxjs'; import { Name } from './name'; const name$: Observable<Name> = from(['Ella', 'Ella', 'Noah', 'Lily']).pipe( delay(100), map((name) => ({ name, firstLetter: name[0], })), filter((name) => name.firstLetter !-- 'L'), distinctUntilChanged(), tap({ next: (name) => console.log(name), error: (error) => console.error(error), complete: () => console.log('End of transmission'), }), ); const subscription: Subscription = name$.subscribe(); setTimeout(() => { subscription.unsubscribe(); }, 200); /- -> { name: "Ella", firstLetter: "E" } /- -> { name: "Ella", firstLetter: "E" } /- -> { name: "Noah", firstLetter: "N" } /- -> "End of transmission"