0001    import Foundation
0002    
0003    public extension Transform {
0004        /**
0005         A provided transformation function (see Transform and Mapper for uses) in order to create a dictionary
0006         from an array of values. The idea for this is to create a dictionary based on an array of values,
0007         using a custom function to extract the key used in the dictionary
0008    
0009         Example:
0010    
0011         // An enum with all possible HintIDs
0012         enum HintID: String {
0013            ...
0014         }
0015    
0016         // A hint struct, which consists of an id and some text
0017         struct Hint: Mappable {
0018            let id: HintID
0019            let text: String
0020    
0021            init(map: Mapper) throws {
0022                try id   = map.from("id")
0023                try text = map.from("text")
0024            }
0025         }
0026    
0027         // An object that manages all the hints
0028         struct HintCoordinator: Mappable {
0029            private let hints: [HintID: Hint]
0030    
0031            ...
0032    
0033            init(map: Mapper) throws {
0034                // Use the `toDictionary` transformation to create a map of `Hint`s by their `HintID`s
0035                try hints = map.from("hints", transformation: Transform.toDictionary { $0.id })
0036            }
0037         }
0038    
0039         - parameter key:    A function to extract the key U from an instance of the Mappable object T
0040         - parameter object: The AnyObject? to attempt to produce the objects and dictionary from, this is
0041                             AnyObject? to allow uses with transformations (see Mapper), if it is not an array of
0042                             NSDictionaries a `MapperError` is thrown
0043    
0044         - throws: `MapperError` if the given `object` is not an array of NSDictionaries
0045    
0046         - returns: A dictionary of [U: T] where the keys U are produced from the passed `key` function and the
0047                    values T are the objects
0048         */
0049        @warn_unused_result
0050        public static func toDictionary<T, U where T: Mappable, U: Hashable>(key getKey: T -> U) ->
0051            (object: AnyObject?) throws -> [U: T]
0052        {
0053            return { object in
0054                guard let objects = object as? [NSDictionary] else {
0055                    throw MapperError()
0056                }
0057    
0058                var dictionary: [U: T] = [:]
0059                for object in objects {
0060                    let model = try T(map: Mapper(JSON: object))
0061                    dictionary[getKey(model)] = model
0062                }
0063    
0064                return dictionary
0065            }
0066        }
0067    }
0068