Using Reduce to sum (Swift)

Im looking through examples were you can use reduce to sum an array, but mostly finding examples with numbers.
How would you add up all `Bar` that are inside `Foo` that has `isAvailable` set to `true` using `reduce()`?

Would you prefer to write it as I’ve done it? (readability & efficiency in mind)

``````struct Foo {
var isAvailable: Bool
var bars: [Bar]
}

struct Bar {
var name: String
}

let array = [
Foo(isAvailable: true, bars: [ Bar(name: "Bill"), Bar(name: "Donald") ]),
Foo(isAvailable: false, bars: [ Bar(name: "Barack"), Bar(name: "Joe") ]),
Foo(isAvailable: true, bars: [ Bar(name: "George"), Bar(name: "Ronald") ])
]

// Do this with reduce??
var totalCount = 0
for foo in array where foo.isAvailable {
totalCount += foo.bars.count
}
``````

>Solution :

In a short way:

``````let reduced = array.reduce(0) { \$1.isAvailable ? \$0 + \$1.bars.count : \$0 }
``````

Now, let’s explicit it:

The logic is quite simple:

• We set the initial value to 0
• In the closure, we have two parameters, the first one is the current value (at start it’s the initial value), which we’ll increment at each iteration, and the second one is the element of the array. We return then the new value (partial) that we incremented or not according to your condition (here is `isAvailable`)

Explicitly:

``````let reduced2 = array.reduce(0) { partial, current in
if current.isAvailable {
return partial + current.bars.count
} else {
return partial
}
}
``````

With a ternary if:

``````let reduced3 = array.reduce(0) { partial, current in
return current.isAvailable ? partial + current.bars.count : partial
}
``````

Getting rid of the `return`, see `Functions With an Implicit Return` in Functions of Swift or `Implicit Returns from Single-Expression Closures` of Closures of Swift.

``````let reduced4 = array.reduce(0) { partial, current in
current.isAvailable ? partial + current.bars.count : partial
}
``````

With `Shorthand Argument Names` on Closures of Swift.

``````let reduced5 = array.reduce(0) { \$1.isAvailable ? \$0 + \$1.bars.count : \$0 }
``````