Let's say I have an array of closures that I want to run on every UITouch. Here's the code I use:
touches.filter { touch in
return touch.phase == .Ended && touch.tapCount == 1
}.forEach { touch in
actionsOnTap.forEach { action in
action(touch)
}
}
It bugs me that there's nested forEach statement, and I guess there's some clean way that can be applied exactly for that case, but I can't think of it. Can anyone give me a hint?
Personally, I like the nesting. I would write:
for touch in touches {
if touch.phase == .Ended {
if touch.tapCount == 1 {
actionsOnTap.forEach {$0(touch)}
}
}
}
To me, that's clean and (above all) clear.
You should definitely eliminate the filter
from your logic and possibly use a guard
inside the first loop instead, for the sake of efficiency and conciseness. I also agree with @Rob's and @matt's suggestion of using a traditional for loop instead of forEach
– at least for the first loop.
Although a (maybe even cleaner) alternative is the integrate the touch conditional logic into the for
loop directly through using the where
clause, as well as possibly folding your forEach
into a single line (whichever you find more readable).
I'd write it like this:
for touch in touches where touch.phase == .Ended && touch.tapCount == 1 {
actionsOnTap.forEach{$0(touch)}
}
This is a good example of why forEach
is not a universal (or even appropriately common) replacement for for-in
. This code become shorter (140 chars vs 186 chars) and clearer just using a traditional for
loop:
for touch in touches where touch.phase == .Ended && touch.tapCount == 1 {
for action in actionsOnTap {
action(touch)
}
}
It also doesn't create an extra array copy the way the filter
does. This isn't a general reason not to use filter
. filter
is a very powerful tool that should be used often, but in this case, it's clearer and more efficient to use for
.
Edited to use @originaluser2's suggestion of where
rather than guard
. That probably is better Swift.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With