Here's a sketch of how it might be done. It uses a tuple return from the element closure, rather than your f1($0) : f2($0)
pseudo-code. Note that the tuple elements can be any type, so long as the first (which will be used as the key) is hashable.
let collection = [1, 2, 3, 4, 5]
/* OP's requested form:
let dictionary: [Int : String] = collection.map{
$0 : "Number: \($0)"
}
*/
// Return a tuple of (key, value) from the closure...
extension CollectionType {
func mapd<Tk: Hashable, Tv>(elementClosure: (Self.Generator.Element) -> (Tk, Tv) ) -> [Tk : Tv] {
var returnDict = [Tk : Tv]()
for i in self {
let (k, v) = elementClosure(i)
returnDict[k] = v
}
return returnDict
}
}
let dictionary: [Int : String] = collection.mapd{ ($0, "Number: \($0)") }
print("\(dictionary)") // "[5: "Number: 5", 2: "Number: 2", 3: "Number: 3", 1: "Number:1]"
// Neither of the dictionary's elements need be the type of the collection,
// it's entirely up to what the closure returns.
let dictionary2: [Double : String] = collection.mapd{ (Double($0), "Number: \($0)") }
print("\(dictionary)") // "[5: "Number: 5", 2: "Number: 2", 3: "Number: 3", 1: "Number:1]"