9

I want to improve on a closure I wrote using Swift's Array.map function

I'm basically taking an Array and remapping all of its elements using a closure.

// Here's the array:
var numbersArray = [1, 2, 3, 4, 5]

// Here's the closure - it takes whatever number is passed into it and 
// multiplies it by 2.0
var multiplier = {  (currentNum: Int) -> Double in
    let result = Double(currentNum) * 2.0
    return result
}

// And here's how I'm calling it:
var newArray = numbersArray.map(multiplier)

And this works perfectly.

But what if I want to multiply everything by 2.1? or 3.5? or any value? In other words, what if I want to make the amount I multiply by also be a variable? And have it be passed into the closure as a second argument?

I tried adding it to the argument list like this:

var multiplier = {  (currentNum: Int, factor: Double) -> Double in
    let result = Double(currentNum) * factor
    return result
}

and then changing my call to this:

var newArray = numbersArray.map(multiplier, 3.5)

but I'm getting all sorts of errors (and I tried all sorts of variations on this of course.)

What am I doing wrong?

2 Answers 2

14

You can use a higher order function to produce a custom function that you can then use with the array's map function. Like this:

var numbersArray = [1, 2, 3, 4, 5]

func multiplier(factor: Double) -> (Int)->Double
{
    return {  (currentNum: Int) -> Double in
        let result = Double(currentNum) * factor
        return result
    }
}

var newArray = numbersArray.map(multiplier(2.5))
Sign up to request clarification or add additional context in comments.

4 Comments

That's pretty bad-ass :-) Very clever. Is that pretty much the only way to do this?
It's the only way I can think of at least. I'm not really a master of functional programming though
Fair enough. Even if its not the only or "best" way to do this, its certainly plenty cool. I'll credit you for right answer. Cheers :-)
No need to be modest, @connor -- that's good functional programming. :) You'll find some examples much like that in the Swift book, IIRC.
14

Edit: Note: This language feature was removed in Swift 2.

A swift-er way than connor's answer (but along the same lines), is to use a curried function. From The Swift Programming Language->Language Reference->Declarations->Curried Functions and Methods:

A function declared this way is understood as a function whose return type is another function.

So you can simplify this:

func multiplier(factor: Double) -> (Int)->Double
{
    return {  (currentNum: Int) -> Double in
        let result = Double(currentNum) * factor
        return result
    }
}

to this:

func multiplier(factor: Double)(currentNum: Int) -> Double {
    return Double(currentNum) * factor
}

and use it exactly the same way:

let numbersArray = [1, 2, 3, 4, 5]
let multipliedArray = numbersArray.map(multiplier(3.5))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.