我有一个变量,它是一个枚举值数组.这些值随时间而变化.
enum Option {
case One
case Two
case Three
}
let options = Variable<[Option]>([ .One, .Two, .Three ])
Run Code Online (Sandbox Code Playgroud)
然后我观察这个变量的变化.问题是,我需要知道最新值和前一个值之间的差异.我现在正在这样做:
let previousOptions: [Option] = [ .One, .Two, .Three ]
...
options
.asObservable()
.subscribeNext { [unowned self] opts in
// Do some work diff'ing previousOptions and opt
// ....
self.previousOptions = opts
}
Run Code Online (Sandbox Code Playgroud)
是否内置了RxSwift可以更好地管理它?有没有办法始终从信号中获取先前值和当前值?
小智 20
这是一个方便的通用扩展,应该涵盖这些"我想要前一个和当前值"的用例:
extension ObservableType {
func withPrevious(startWith first: E) -> Observable<(E, E)> {
return scan((first, first)) { ($0.1, $1) }.skip(1)
}
}
Run Code Online (Sandbox Code Playgroud)
ric*_*chy 11
另一种方式作为扩展
extension ObservableType {
func withPrevious() -> Observable<(E?, E)> {
return scan([], accumulator: { (previous, current) in
Array(previous + [current]).suffix(2)
})
.map({ (arr) -> (previous: E?, current: E) in
(arr.count > 1 ? arr.first : nil, arr.last!)
})
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
someValue
.withPrevious()
.subscribe(onNext: { (previous, current) in
if let previous = previous { // previous is optional
print("previous: \(previous)")
}
print("current: \(current)")
})
.disposed(by: disposeBag)
Run Code Online (Sandbox Code Playgroud)
Pha*_*oan 10
你去吧
options.asObservable()
.scan( [ [],[] ] ) { seed, newValue in
return [ seed[1], newValue ]
}
// optional, working with tuple of array is better than array of array
.map { array in (array[0], array[1]) }
//optional, in case you dont want empty array
.skipWhile { $0.count == 0 && $1.count == 0 }
Run Code Online (Sandbox Code Playgroud)
它会返回Observable<([Options], [Options])>
:)
Pham Hoan说,这scan(_)
是工作的正确工具.Marin Todorov撰写了一篇关于做到这一点的好文章.
基于Marin的帖子,这就是我提出的内容:
options
.asObservable()
.scan([]) {
(previous, current) in
return Array(previous + [current]).suffix(2)
}
.subscribeNext {
(lastTwoOptions) in
let previousOptions = lastTwoOptions.first
let currentOptions = lastTwoOptions.last
// Do your thing. Remember to check for nil the first time around!
}
.addDisposableTo(self.disposeBag)
Run Code Online (Sandbox Code Playgroud)
希望有所帮助
该.pairwise()
运营商不正是你想要的,是做做最简单的方法。此运算符将成对的连续发射组合在一起,并将它们作为包含两个值的数组发射。
见:http : //reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-pairwise
或https://rxjs-dev.firebaseapp.com/api/operators/pairwise
更新:正如@courteouselk 在他的评论中指出的那样,我没有注意到这是一个 RxSwift 问题,我的回答引用了一个 RxJS 解决方案(糟糕!)。
原来RxSwift并没有有一个内置的pairwise
运营商,但RxSwiftExt提供了成对类似于内置RxJS运营商的扩展操作。
归档时间: |
|
查看次数: |
10803 次 |
最近记录: |