import { IterableX } from '../iterablex' ; import { identity } from '../../util/identity' ; import { arrayIndexOf } from '../../util/arrayindexof' ; import { comparer as defaultComparer } from '../../util/comparer' ; import { MonoTypeOperatorFunction } from '../../interfaces' ; import { DistinctOptions } from './distinctoptions' ; export class DistinctIterable < TSource , TKey = TSource > extends IterableX < TSource > { private _source : Iterable < TSource > ; private _keySelector : ( value : TSource ) => TKey ; private _cmp : ( x : TKey , y : TKey ) => boolean ; constructor ( source , keySelector , cmp ) { super ( ) ; this . _source = source ; this . _keySelector = keySelector ; this . _cmp = cmp ; } * [ Symbol . iterator ] ( ) { const set = [ ] as TKey [ ] ; for ( const item of this . _source ) { const key = this . _keySelector ( item ) ; if ( arrayIndexOf ( set , key , this . _cmp ) === - 1 ) { set . push ( key ) ; yield item ; } } } } template TSource template TKey param { DistinctOptions < TSource , TKey > } options returns { MonoTypeOperatorFunction < TSource > } export function distinct < TSource , TKey = TSource > ( options ? ) { return function distinctOperatorFunction ( source ) : IterableX < TSource > { const { [ 'keySelector' ] : keySelector = identity , [ 'comparer' ] : comparer = defaultComparer } = options || { } ; return new DistinctIterable < TSource , TKey > ( source , keySelector ! , comparer ! ) ; } ; }