2016-02-23 2 views
2

Кажется, что rx-swift еще не реализован DefaultIfEmpty. Есть ли другой способ воспроизвести это поведение?RxSwift эквивалент DefaultIfEmpty

let myList:[Int] = [] 
myList.toObservable() 
    .switchIfEmpty {() in // <- Not (yet?) implemented 
     return Observable.of(1) 
    }.subscribeNext { num in 
     print(num) 
    } 

// prints 1 

ответ

0

Я использовал toArray, чтобы имитировать это поведение. Пример с PublishSubject (может быть легко преобразован для использования myList, я надеюсь):

let subjectInt = PublishSubject<Int>() 
    let emptyReplacement = subjectInt 
    .toArray() 
    .filter {$0.isEmpty} 
    .map{ _ in return 42} 

    let defaultIfEmpty = [subjectInt, emptyReplacement].toObservable().merge() 

    defaultIfEmpty.subscribeNext { 
    print("defaultIfEmpty: \($0)") 
    } 

    subjectInt.on(.Next(11)) // 
    subjectInt.on(.Next(33)) //comment these 2 lines out to see the default value 42 printed 
    subjectInt.on(.Completed) 
1

У меня была аналогичная проблема, но нужно только 1 значение от наблюдаемого так простое решение конкатенации и не принимать 1:

yourSingleObservable.concat(Observable.just(defaultValue)).take(1) 
0

Для уточнения того, что сказал Михал, toArray() предлагает решение:

extension Observable { 
    func defaultIfEmpty(_ other: Observable<E>) -> Observable<E> { 
     let replacement = toArray() 
      .flatMap { array -> Observable<E> in 
       if array.isEmpty { 
        return other 
       } else { 
        return Observable.empty() 
       } 
      } 

     return concat(replacement) 
    } 
} 

Использование:

let a = Observable.of(1, 2, 3) 
let b = Observable.of(-1, -2, -3) 
let c = Observable<Int>.of() 

_ = a.defaultIfEmpty(b).subscribe(onNext: { print($0) }) 

// 1 
// 2 
// 3 

_ = c.defaultIfEmpty(b).subscribe(onNext: { print($0) }) 

// -1 
// -2 
// -3 
Смежные вопросы