Skip to content

Instantly share code, notes, and snippets.

@alldne
Created July 16, 2020 06:57
Show Gist options
  • Save alldne/7e2fae33bc6f814b9990f744c4f6f9e0 to your computer and use it in GitHub Desktop.
Save alldne/7e2fae33bc6f814b9990f744c4f6f9e0 to your computer and use it in GitHub Desktop.
distinctUntilChangedInGroup
extension ObservableType {
/**
Returns an observable sequence that contains only distinct contiguous elements in a virtual group by key.
For example,
Original stream:
(A, 1), (A, 2), (B, 100), (A, 2), (A, 2), (B, 101), (A, 3)
distinctUntilChanged
(A, 1), (A, 2), (B, 100), (A, 2), (B, 101), (A, 3)
distinctUntilChangedGrouped:
(A, 1), (A, 2), (B, 100), (B, 101), (A, 3)
where we group the elements by the first element in tuples so that the elements are grouped by 'A' and 'B'.
- Parameters:
- groupSelector: A function to compute the key to group elements.
- comparer: Equality comparer for elements.
- Returns:
An observable sequence only containing the distinct contiguous elements in a virtual group from the given key.
*/
public func distinctUntilChangedInGroup<GroupKey: Hashable>(
groupSelector: @escaping (Element) -> GroupKey,
comparer: @escaping (Element, Element) -> Bool
) -> Observable<Element> {
return Observable.create { observer in
var lastElements: [GroupKey: Element] = [:]
return self.subscribe { (event) in
switch event {
case .next(let element):
let key = groupSelector(element)
let old = lastElements[key]
lastElements[key] = element
if let old = old, comparer(old, element) {
// exist & same -> do nothing
} else {
observer.onNext(element)
}
case .completed:
observer.onCompleted()
case .error(let error):
observer.onError(error)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment