This is Understanding Combine, written by Matt Neuburg. 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 (and final) editions are iOS 15 Programming Fundamentals with Swift and Programming iOS 14. Thank you!


Max, Min, Count

.max (Publishers.Comparison) is just like the max sequence method. In effect, it’s a specialized version of .reduce: it accumulates the previous output and receives the current upstream value, and returns the larger of the two, so that at the end the accumulated value is the largest value received from upstream.

If the value type is a Comparable, you can omit the comparison function and let the operator use its default function, which uses < to determine relative order; or you can supply a function and decide manually whether the parameters are ordered smaller–larger, returning a Bool to indicate whether that’s the case.

There is also .tryMax, which works as you would expect.

.min (Publishers.Comparison) is just like .max, except that the maintained value is the smaller of the two compared values. Again, if the value type is a Comparable, you can omit the comparison function; if you supply it, you return a Bool indicating whether the parameters are ordered smaller–larger.

And there is also .tryMin, which works as you would expect.

So for example:

[1,2,3].publisher
    .max() // 3
[1,2,3].publisher
    .max {
        $0 < $1 // same as what the default does
    } // 3
[1,2,3].publisher
    .max {
        let names = ["one", "two", "three"]
        return names[$0-1] < names[$1-1]
    } // 2, because "two" is the "largest" alphabetically
[1,2,3].publisher
    .min {
        let names = ["one", "two", "three"]
        return names[$0-1] < names[$1-1]
    } // 1, because "one" is the "smallest" alphabetically

.count (Publishers.Count) just counts the incoming values, accumulating the count, and reports that count when a .finished completion is received (and then sends a .finished completion). So it is the equivalent of

.reduce(0) {prev,_ in $0+1}

If the upstream sends a .finished completion without having emitted any values, the .count operator reports 0, as you would expect.


Table of Contents