sirab333
sirab333

Reputation: 3722

Swift Array.map closure issue

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?

Upvotes: 9

Views: 7907

Answers (2)

Jack Lawrence
Jack Lawrence

Reputation: 10772

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))

Upvotes: 14

Connor
Connor

Reputation: 64644

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))

Upvotes: 14

Related Questions