为什么在这些示例中skipWhile的行为有所不同?

时间:2019-07-18 05:14:42

标签: swift rx-swift

在第一个示例中,我的终端输出

next(1)
next(2)
next(3)
next(4)
next(5)
next(6)
next(7)
next(8)
next(9)
next(10)
completed

在第二个示例中,它将输出

next(3)
next(6)
next(8)
next(9)
completed

我知道每个值都不相同,但是我希望第一个示例应用了过滤,因此它遵循了我的.skipWhile { $0 % 2 == 0 }块中的逻辑

func skipWhile() {
    let bag = DisposeBag()

    Observable
        .from(Array(1...10))
        .skipWhile { $0 % 2 == 0 }
        .subscribe { print($0) }
        .disposed(by: bag)

    Observable
        .from([2,3,6,8,9])
        .skipWhile { $0 % 2 == 0 }
        .subscribe { print($0) }
        .disposed(by: bag)

}
skipWhile()

1 个答案:

答案 0 :(得分:2)

skipWhile不是filter。在谓词为true时,它将在可观察对象生命周期的开始时跳过元素。一旦出现一个不再满足谓词的元素,它就会打开闸门,让其他所有事物通过。

您的第一个可观察词说“跳过所有内容,直到第一个奇数”。第一个元素是奇数,因此不会跳过任何内容,这就是为什么您看到所有数组元素都在打印的原因。

如果您在第二个可观察值中注意到,则您没有过滤掉偶数(因为有8)。您只是跳过了元素,直到第一个奇数(3),导致2被跳过。

旁注

Int.isMultiple(of: )已在Swift 5中添加,我建议您在这种情况下使用它。只是更清楚了,而且避免了由于误读==!=而导致的错误。

Observable
    .from(Array(1...10))
    .skipWhile { $0.isMultiple(of: 2) }
    .subscribe { print($0) }
    .disposed(by: bag)

您甚至可以命名谓词:

let isEven: (Int) -> Bool = { $0.isMultiple(of: 2) }

Observable
    .from(Array(1...10))
    .skipWhile(isEven)
    .subscribe { print($0) }
    .disposed(by: bag)

或者我的最爱,将其添加为计算属性:

extension BinaryInteger {
    var isEven: Bool { return self.isMultiple(of: 2) }
    var isOdd: Bool { return !self.isEven }
}

Observable
    .from(Array(1...10))
    .skipWhile { $0.isEven }
    .subscribe { print($0) }
    .disposed(by: bag)