Some time I need pass external variable to the map() like next code:
let tomap = ["a", "d", "l", "m"]
var currentNumber = 10
let mapped = tomap.map { letter -> String in
var letter = letter
letter += "\(currentNumber)"
currentNumber += 10
return letter
}
currentNumber was captured by map closure. The question is: Is it correct way to use mapping?
cukr
2
Would it do what you want? Yes.
but using non-pure functions for map feels wrong for me and probably most people that like using map
I would do it like this instead:
let mapped = zip(tomap, sequence(first: 10, next: { $0 + 10 })).map {
$0 + "\($1)"
}
3 Likes
Nevin
3
Yes, it is a perfectly correct way to use map. Capturing variables is a basic and fundamental part of how closures work, and if that’s what you want to do, they are the right tool for the job.
I will note that you can make your example shorter by using defer:
let mapped: String = tomap.map {
defer { currentNumber += 10 }
return $0 + "\(currentNumber)"
}
4 Likes
Also, to start with -1 step is a pretty common technique to simplify the loop:
var currentNumber = 0
let mapped = tomap.map { letter -> String in
currentNumber += 10
return letter + "\(currentNumber)"
}
If you want to stop your functional purist friends from squirming, and want to edit in place, you could also use for loop:
var tomap = ...
var currentNumber = 0
for index in tomap.indices {
currentNumber += 10
tomap[index] += "\(currentNumber)"
}
2 Likes