This repository was archived by the owner on Apr 20, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Copy pathdistinct.js
74 lines (65 loc) · 2.64 KB
/
distinct.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};