Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create Swift Dictionary from Array
/**
Creates a dictionary with an optional
entry for every element in an array.
*/
func toDictionary<E, K, V>(
array: [E],
transformer: (element: E) -> (key: K, value: V)?)
-> Dictionary<K, V>
{
return array.reduce([:]) {
(var dict, e) in
if let (key, value) = transformer(element: e)
{
dict[key] = value
}
return dict
}
}
struct Person
{
let name: String
let age: Int
}
let people = [
Person(name: "Billy", age: 42),
Person(name: "David", age: 24),
Person(name: "Maria", age: 99)]
let dictionary = toDictionary(people) { ($0.name, $0.age) }
println(dictionary)
// Prints: [Billy: 42, David: 24, Maria: 99]
@InsertNetan
Copy link

in the spirit of swift 2:
from a global function to CollectionType extension
this way with a given transform function we can map any collectionType into a dictionary.

extension CollectionType {
    func toDictionary<K, V>
        (transform:(element: Self.Generator.Element) -> (key: K, value: V)?) -> [K : V] {
            return self.reduce([:]) { (var dictionary, e) in
                if let (key, value) = transform(element: e){
                    dictionary[key] = value
                }
                return dictionary
            }
    }
}

@Buju77
Copy link

Buju77 commented Dec 21, 2015

@InsertNetan awesome, thx, I was looking for exactly this thing! ;)

@InsertNetan
Copy link

@Buju77 thanks, i'm really glad to hear

@KevM
Copy link

KevM commented Apr 21, 2016

How about this update to make it compatible with Swift 2.2?

extension CollectionType {
    func toDictionary<K, V>
        (transform:(element: Self.Generator.Element) -> (key: K, value: V)?) -> [K : V] {
        var dictionary = [K : V]()
        for e in self {
            if let (key, value) = transform(element: e) {
                dictionary[key] = value
            }
        }
        return dictionary
    }
}

@Buju77
Copy link

Buju77 commented Jun 8, 2016

@KevM nice, thx for the update for Swift 2.2! 👍

@nikolsky2
Copy link

How about this version? Slightly improved snippet from @KevM

extension CollectionType {
    func toDictionary<K, V>(transform:(element: Self.Generator.Element) -> [K: V]) -> [K: V] {
        var dictionary = [K: V]()
        self.forEach { e in
            let dict = transform(element: e)
            for (key, value) in dict {
                dictionary[key] = value
            }
        }
        return dictionary
    }
}

@OliverDimitrov
Copy link

OliverDimitrov commented Oct 5, 2016

Anything about Swift 3 ?

@TheNamesJames
Copy link

TheNamesJames commented Nov 12, 2016

In case people are looking for a Swift 3 version

extension Collection {
    func dictionary<K, V>(transform:(_ element: Iterator.Element) -> [K : V]) -> [K : V] {
        var dictionary = [K : V]()
        self.forEach { element in
            for (key, value) in transform(element) {
                dictionary[key] = value
            }
        }
        return dictionary
    }
}

And you'd use it something like this

let dictionary = people.dictionary { [$0.name : $0.age] }

Or, for those who might prefer an initialiser pattern:

extension Dictionary {
    init<C: Collection>(_ collection: C, transform:(_ element: C.Iterator.Element) -> [Key : Value]) {
        self.init()
        collection.forEach { (element) in
            for (k, v) in transform(element) {
                self[k] = v
            }
        }
    }
}

Which rounds out to

let dictionary = Dictionary(people) { [$0.name : $0.age] }

@eonist
Copy link

eonist commented Apr 25, 2017

What about making this without that var ?

@stefc
Copy link

stefc commented Dec 17, 2017

This is my suggestion of the extension using the reduce(into:) method of the swift standard library

extension Collection {
    func dictionary<K:Hashable, V>(transform:(_ element: Iterator.Element) -> (key:K, value:V)) -> [K : V] {
        return self.reduce(into: [K : V]()) { (accu, current) in
            let kvp = transform(current)
            accu[kvp.key] = kvp.value
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment