0001    //
0002    //  FutureCollections.swift
0003    //  Deferred
0004    //
0005    //  Created by Zachary Waldowski on 8/29/15.
0006    //  Copyright © 2014-2015 Big Nerd Ranch. Licensed under MIT.
0007    //
0008    
0009    import Dispatch
0010    
0011    public extension SequenceType where Generator.Element: FutureType {
0012        /// Choose the future that is determined first from a collection of futures.
0013        ///
0014        /// - returns: A deferred value that is determined with the first of the
0015        ///   given futures to be determined.
0016        var earliestFilled: Future<Generator.Element.Value> {
0017            let combined = Deferred<Generator.Element.Value>()
0018            for future in self {
0019                future.upon {
0020                    combined.fill($0)
0021                }
0022            }
0023            return Future(combined)
0024        }
0025    }
0026    
0027    public extension CollectionType where Generator.Element: FutureType {
0028        /// Compose a number of futures into a single deferred array.
0029        ///
0030        /// - returns: A deferred array that is determined once all the given values
0031        ///   are determined, in the same order.
0032        var joinedValues: Future<[Generator.Element.Value]> {
0033            if isEmpty {
0034                return Future(value: [])
0035            }
0036    
0037            let array = Array(self)
0038            let combined = Deferred<[Generator.Element.Value]>()
0039            let group = dispatch_group_create()
0040    
0041            for deferred in array {
0042                dispatch_group_enter(group)
0043                deferred.upon { _ in
0044                    dispatch_group_leave(group)
0045                }
0046            }
0047    
0048            dispatch_group_notify(group, genericQueue) {
0049                combined.fill(array.map {
0050                    $0.value
0051                })
0052            }
0053    
0054            return Future(combined)
0055        }
0056    }
0057