5

Let's say i have array of any object below , I'm looking for a way to count items in the array as following:

var OSes = ["iOS", "Android", "Android","Android","Windows Phone", 25]

Is there a short way for swift to do something like this below ?

Oses.count["Android"]   // 3 

3 Answers 3

22

A fast, compact and elegant way to do it is by using the reduce method:

let count = OSes.reduce(0) { $1 == "Android" ? $0 + 1 : $0 }

It's more compact than a for loop, and faster than a filter, because it doesn't generate a new array.

The reduce method takes an initial value, 0 in our case, and a closure, applied to each element of the array.

The closure takes 2 parameters:

  • the value at the previous iteration (or the initial value, 0 in our case)
  • the array element for the current iteration

The value returned by the closure is used as the first parameter in the next iteration, or as the return value of the reduce method when the last element has been processed

The closure simply checks if the current element is Android:

  • if not, it returns the aggregate value (the first parameter passed to the closure)
  • if yes, it returns that number plus one
Sign up to request clarification or add additional context in comments.

2 Comments

This is a well-written explanation of reduce(). +1
I always use for case syntax to deal with count specific items in Array. Your method is more swifty.
7

It's pretty simple with .filter:

OSes.filter({$0 == "Android"}).count // 3

3 Comments

reduce is more performant, but I prefer filter().count for readability.
Yup, always compromise between readability and speed / effectivity. Depends on underlying data and amount of them. If it doesn't hurt, I do prefer readability.
There's interesting comment from @AirspeedVelocity regarding performance.
0

Swift 5 with count(where:)

let countOfAndroid = OSes.count(where: { $0 == "Android" })

Swift 4 or less with filter(_:)

let countOfAndroid = OSes.filter({ $0 == "Android" }).count 

2 Comments

count(where:) was briefly with us in Swift 5, but sadly it was removed because of conflicts with the type checking system.
This Swift 5.0 feature was withdrawn in beta testing because it was causing performance issues for the type checker. Hopefully it will come back in time for Swift 5.1, perhaps with a new name to avoid problems. hackingwithswift.com/articles/126/whats-new-in-swift-5-0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.