In a short way:
let reduced = array.reduce(0) { $1.isAvailable ?
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 ?
1.bars.count : $0 }
Answer from Larme on Stack Overflowarrays - Using Reduce to sum (Swift) - Stack Overflow
Adding an index with functional methods like map, reduce, filter - Pitches - Swift Forums
Swift Do Something Useful with Zip, Map, and Reduce
A question about this:
What's the difference between applying a mapping function on an array vs doing .forEach?
More on reddit.comShorthand map, filter, reduce. Is it just syntactical sugar?
It’s not about performance (although there is potential for that) but about keeping your code clean, simple, and concise. There’s also no mutation and less room for error.
+ referring to the function in this way looks like a special case but it’s no different if it was a regular function like func add(a: Int, b: Int) -> Int and you then wrote reduce(ns, add). + returns a function that you can pass around because Swift has first-class functions.
Videos
In a short way:
let reduced = array.reduce(0) { $1.isAvailable ?
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 ?
1.bars.count : $0 }
You can achieve this using a single reduce operation. Start from a 0 result, then in the closure, check foo.isAvailable and only increment the count if it is true.
let totalCount = array.reduce(0, { accumulatingResult, foo in
guard foo.isAvailable else { return accumulatingResult }
return accumulatingResult + foo.bars.count
})