Functional Snippet #9: Map for Optionals

We’ve already talked about the map function for arrays in a previous snippet. In case you’re not familiar with it, map transforms an array into a new array with the same size by applying a transform function to each element. For example:

let urls: [NSURL] = [ /* a bunch of image URLs */ ]
let images: [NSImage?] = { NSImage(contentsOfURL: $0) }

However, map can not only be defined for arrays. On a more abstract level, map simply unwraps values from a container type, applies a transform, and wraps them again. For example, we can also define it for optionals (it’s already in the standard library, but you could easily write it yourself):

func map<A, B>(x: A?, f: A -> B) -> B? {
    if let x1 = x {
        return f(x1)
    return nil

Let’s say we wanted to transform an optional URL into an optional NSImage, similar to the above array example. One approach would be to use Swift’s optional binding:

let url: NSURL? = NSURL(string: "image.jpg")
var image: NSImage?
if let url1 = url {
    image = NSImage(contentsOfURL:url1)

By using map we can solve this in a much more succinct way though:

let url: NSURL? = NSURL(string: "image.jpg")
let image = map(url) { NSImage(contentsOfURL: $0) }

map can be defined on many types, including dictionaries, tuples, functions and your own types.

Stay up-to-date with our newsletter or follow us on Twitter.

Back to the Blog

recent posts