This is Understanding Combine, written by Matt Neuburg. It is a work in progress. Corrections and suggestions are greatly appreciated (you can comment here). So are donations; please consider keeping me going by funding this work at http://www.paypal.me/mattneub. Or buy my books: the current editions are iOS 13 Programming Fundamentals with Swift and Programming iOS 13. Thank you!


Contains, AllSatisfy

.contains (Publishers.Contains) reports, as a Bool, whether a certain value, which you supply as the parameter, is present among the values arriving from upstream. The value type must be an Equatable so that normal equality comparison can be used.

As you might expect, this operator can be short-circuited: that is, if the target value arrives from upstream, the operator immediately knows that the answer is true, so it cancels the upstream and emits true followed by a .finished completion. But the only way to know that the answer is false is to wait until all the upstream values have arrived and a .finished completion has been received.

.contains(where:) (Publishers.ContainsWhere) is similar to .contains, but instead of a value to compare to, you supply a function that receives the incoming value from upstream and returns a Bool, where true means to short-circuit the test and return true now, and false means to wait for the next value. This operator will emit false only when a .finished completion has been received.

So, for example:

[1,2,3].publisher
    .contains(2) // true
[1,2,3].publisher
    .contains { $0 > 1 } // true
[1,2,3].publisher
    .contains { $0 < 1 } // false, after completion

.tryContains(where:) (Publishers.TryContainsWhere) is just like .contains(where:) except that the function can throw, in which case it cancels the upstream and the error is sent down the pipeline as a failure.

.allSatisfy (Publishers.AllSatisfy) reports, as a Bool, whether all the values arriving from upstream pass a certain test. It takes a function that receives the value from upstream and returns a Bool.

As you might expect, this operator can be short-circuited: if the function returns false, the operator immediately knows that the overall answer is false, so it cancels the upstream and emits false followed by a .finished completion. But if the function returns true, the operator has to wait for the next value, and will emit true only when a .finished completion has been received.

For example:

[1,2,3].publisher
    .allSatisfy { $0 % 2 == 0 } // false
[1,2,3].publisher
    .allSatisfy { $0 > 0 } // true, after completion

.tryAllSatisfy (Publishers.TryAllSatisfy) is just like .allSatisfy except that the function can throw, in which case it cancels the upstream and the error is sent down the pipeline as a failure.


Table of Contents