Skip to content

Instantly share code, notes, and snippets.

@erica
Last active June 29, 2017 17:03
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erica/a0bf9f2fb8243f197f7de0d585a75b8a to your computer and use it in GitHub Desktop.
Save erica/a0bf9f2fb8243f197f7de0d585a75b8a to your computer and use it in GitHub Desktop.
import Dispatch
/// Dispatch options for `forEach` loops
public enum ForEachClosureDispatch {
case sequential
case concurrent
}
extension Sequence {
/// Calls the given closure on each element in the sequence in the same order
/// as a `for`-`in` loop.
///
/// The two loops in the following example produce the same output:
///
/// let numberWords = ["one", "two", "three"]
/// for word in numberWords {
/// print(word)
/// }
/// // Prints "one"
/// // Prints "two"
/// // Prints "three"
///
/// numberWords.forEach { word in
/// print(word)
/// }
/// // Same as above
///
/// Using the `forEach` method is distinct from a `for`-`in` loop in two
/// important ways:
///
/// 1. You cannot use a `break` or `continue` statement to exit the current
/// call of the `body` closure or skip subsequent calls.
/// 2. Using the `return` statement in the `body` closure will exit only from
/// the current call to `body`, not from any outer scope, and won't skip
/// subsequent calls.
///
/// - Parameter approach: a flag that controls whether the
/// body should be dispatched asynchronously or performed sequentially
/// - Parameter body: A closure that takes an element of the
/// sequence as a parameter.
@_inlineable
public func forEach(
_ approach: ForEachClosureDispatch = .sequential,
_ body: @escaping (Element) throws -> Void
) rethrows {
for element in self {
switch approach {
case .sequential:
try body(element)
case .concurrent:
DispatchQueue.global().async {
do {
try body(element)
} catch { fatalError("\(error)") }
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment