2016-03-17 16 views
5

Tôi có Biến số là một mảng giá trị enum. Những giá trị này thay đổi theo thời gian.Giá trị hiện tại và giá trị trước đó có thể quan sát

enum Option { 
    case One 
    case Two 
    case Three 
} 

let options = Variable<[Option]>([ .One, .Two, .Three ]) 

Sau đó, tôi quan sát biến này để thay đổi. Vấn đề là, tôi cần phải biết sự khác biệt giữa giá trị mới nhất và giá trị trước đó. Tôi hiện đang làm điều này:

let previousOptions: [Option] = [ .One, .Two, .Three ] 

... 

options 
    .asObservable() 
    .subscribeNext { [unowned self] opts in 
     // Do some work diff'ing previousOptions and opt 
     // .... 
     self.previousOptions = opts 
    } 

Có điều gì đó được xây dựng trong RxSwift để quản lý tốt hơn không? Có cách nào để luôn nhận được các giá trị trước đó và hiện tại từ tín hiệu không?

Trả lời

5

có bạn đi

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 } 

nó sẽ trở lại Observable<([Options], [Options])> :)

3

Như Phạm Hoàn cho biết, scan(_) là công cụ thích hợp cho công việc. Marin Todorov đã viết một số good post để thực hiện chính xác điều này.

Đây là những gì tôi đã đưa ra, dựa trên bài 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) 

Hy vọng rằng sẽ giúp

5

Đây là một phần mở rộng generic tiện dụng, mà nên bao gồm những "Tôi muốn trước đó và hiện tại giá trị" trường hợp sử dụng:

extension ObservableType { 

    func withPrevious(startWith first: E) -> Observable<(E, E)> { 
     return scan((first, first)) { ($0.1, $1) }.skip(1) 
    } 
} 
0

tôi sẽ đề nghị một cái gì đó như thế này (đối với du khách trong tương lai):

options.asObservable() 
     .map { (old: [], new: $0) } // change type from array to tuple 
     .scan((old: [], new: [])) { previous, current in 
      // seed with an empty tuple & return both information 
      return (old: previous.new, new: current.new) 
     } 
     .subscribe(onNext: { option in 
      let oldArray = option.old // old 
      let newArray = option.new // new 
     } 
     .addDisposableTo(disposeBag) 
Các vấn đề liên quan