Short description of the issue:
The implementation of distinctUntilChanged in extension ObservableType where E: Equatable doesn't cover the case of arrays of equatable objects.
example:
Expected outcome:
Since there is an obvious default meaning of `untilChanged with arrays of equatables, I expect that I don't need to pass a closure to the operator.
What actually happens:
distinctUntilChanged() won't compile without a closure { $0 == $1 }
Self contained code example that reproduces the issue:
struct ThisIsEquatable: Equatable {
public static func == (rhs: ThisIsEquatable, lhs: ThisIsEquatable) -> Bool {
return true
}
}
let equatables = (0..<10).map { _ in ThisIsEquatable() }
Observable.of(equatables).distinctUntilChanged()
RxSwift/RxCocoa/RxBlocking/RxTest version/commit
3.5.0
Platform/Environment
How easy is to reproduce? (chances of successful reproduce after running the self contained code)
Xcode version:
8.3.2
:warning: Fields below are optional for general issues or in case those questions aren't related to your issue, but filling them out will increase the chances of getting your issue resolved. :warning:
Installation method:
I have multiple versions of Xcode installed:
(so we can know if this is a potential cause of your issue)
Level of RxSwift knowledge:
(this is so we can understand your level of knowledge
and formulate the response in an appropriate manner)
Hi @tsabend ,
yes, this is a awkward limitation of Swift compiler. We are expecting this to be solved on language level, otherwise we need to define extensions for all known types + Equatable.
Fair enough. I wonder if it's worth adding a shim for Arrays since it's a pretty common case, but not a big deal.
I would agree with @kzaher
But I guess you can add this convenience extension to your library
extension ObservableType where E: Sequence, E.Iterator.Element: Equatable {
func distinctUntilChanged() -> Observable<E> {
return distinctUntilChanged { (lhs, rhs) -> Bool in
return Array(lhs) == Array(rhs)
}
}
}
But I feel like this could be inefficient if you operating on big sequences, but anyway overall should be O(n) time
@sergdort I think this is a good enough rule of thumb solution.
@tsabend I would rather not add this to this library at the moment.
Makes sense. Thanks for taking a look.
This may be solvable in a coming Swift version:
https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
The reason I arrived here, is that I have a lot of subscriptions to arrays in global state (ReSwift), and as a result, I have a lot of distinctUntilChanged { $0 == $1 }. Aside from the runtime cost, there is a high compile time cost -- sometimes more than a second per each.
Most helpful comment
I would agree with @kzaher
But I guess you can add this convenience extension to your library