Blog

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?] = urls.map { 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