How to Map Over a Dictionary in Swift

You may be familiar with the map(_:) method in Swift that can be called on arrays. This allows you to pass in a closure that gets executed on each item of the array, transforming the element in some way. The result is a new array of transformed items.

It’s also possible to map over a dictionary using the same syntax. In the closure you pass into this function, you’ll have access to a tuple which contains the key and value of the dictionary item. The output of the map function is a new collection, based on the return type of the closure you passed in.

Very often you’ll use the shorthand syntax for this, but I’ll include the full syntax below as well.

let scores = ["James": 6, "Francisco": 2, "Brittany": 1]

// Full syntax
let scoreList = scores.map { (name, score) -> String in
    "\(name): \(score)"
}

// Shorter syntax (omitting return type of closure)
let scoreList = scores.map({ (name, score) in
    "\(name): \(score)"
})

// Shorthand syntax
let scoreList = scores.map { "\($0.key): \($0.value)" }

The result of each of these calls is an array of strings as:

["Brittany: 1", "James: 6", "Francisco: 2"]

Mapping Over the Values in a Dictionary

If you would like you transform only the values of a dictionary, leaving the keys intact, you can use the mapValues(_:) method. This function takes in a closure, where you’ll have access to the dictionary item’s value that you can modify. The mapValues(_:) method returns a new dictionary identical to the original, but with new values based on the transform that was applied.

let scores = ["James": 6, "Francisco": 2, "Brittany": 1]

// Full syntax
let addBonusPoint = scores.mapValues { value -> Int in
    value + 1
}

// Shorter syntax (omitting return type of closure)
let addBonusPoint = scores.mapValues { value in
    value + 1
}

// Shorthand syntax
let addBonusPoint = scores.mapValues { $0 + 1 }

Each of these mapValues(_:) calls outputs a new dictionary of:

["Brittany": 2, "James": 7, "Francisco": 3]