Ask Erica: How do I count with reduce?

“how do I use reduce() to get number of items in an array that aren’t nil?”

Here’s an answer:

let exampleArray: [Int?] = [1, 3, nil, 4, nil, 10]
print(exampleArray.reduce(0, combine:{return $0 + ($1.map{_ in 1} ?? 0)}))

But I think you’d be better using flatMap or for case

print(exampleArray.flatMap({$0}).count)

var count = 0; for case _? in exampleArray {count += 1}; print(count)

Or you might think about why you’re counting items instead of just using the result of flatMap directly.

6 Comments

  • I think your approach using `map` is unnecessary. IMO this is a little cleaner.

    let exampleArray: [Int?] = [1, 3, nil, 4, nil, 10]
    print(exampleArray.reduce(0) { $0 + ($1 == nil ? 0 : 1) })

    But overall, I agree that using flatMap or filter here is the better approach.

    • I just kind of liked the opportunity of using map for “if not nil”. It was a conscious choice to be “cute”.

  • This is even shorter, but not as cute:

    print(exampleArray.reduce(0, combine: { $0 + ($1 ?? 0) }))

    • Sadly, won’t work. You need $1 to be $1/$1 and division by nil can be ugly

  • I’m new to Swift/iOS development so maybe missed something. But trying these lines verbatim in a playground had unexpected results. Instead of 4 I got 11, 7 and 6 respectively.