Reputation: 19954
I'm trying to understand how .map
works and all of my searches are returning examples that aren't helping me resolve my issue. From my understanding .map
is a cleaner way of performing a for-in loop, the only difference is that .map
replaces your original creates a new array and for-in just alters your original arrays values.
In the code example below, I'm expecting the .map
function to replace my wheels array with new Tire objects whose state properties are all set to .Flat
.
This is a playground-ready version of what I'm trying to accomplish in my program:
enum State {
case Ok, Flat
}
class Tire {
var state = State.Ok
init(t: State) {
state = t
}
}
var wheels = [Tire(t: .Ok), Tire(t: .Ok), Tire(t: .Ok)]
wheels = wheels.map { $0.state = .Flat }
error: cannot convert value of type '()' to closure result type 'Tire' wheels = wheels.map { $0.state = .Flat } ~~~~~~~~~^~~~~~~
In the given situation, how can I set all of my Tire objects states to .Flat
using .map
?
Upvotes: 7
Views: 15082
Reputation: 41226
There are 2 similar key functions which perform similar operations, the basic purpose of which is to take an array and build another array from it:
func map(transform:(R)->T) -> [T] --- Map takes an array of elements of one type and converts it to an array of elements of (potentially) another type, by calling a transform function on each element in turn. So you can convert an array of Int's to an array of strings:
[1, 2, 3, 4].map { "\($0)" } // --> ["1", "2", "3", "4"]
func filter(predicate:(T)->Boolean) -> [T] -- Filter takes an array of elements and converts it to an array of elements of the same type, but only includes those elements for which predicate returns true. So you can filter an array of ints to leave only the even numbers:
[1, 2, 3, 4].filter { $0 % 2 == 0 } // --> [ 2, 4]
There are other variants, such as flatMap
which takes [[T]] and turns it into [T] by iterating over the input and array and appending the contents of each array to an output array:
[ [1, 2], [3, 4]].flatMap() // --> [1, 2, 3, 4]
It's also worth nothing that the concept behind map
is that, in simplistic terms, it can be used to map any input type to an output type, so you can define:
func <R, T> map(in:R?, transform:(R)->T) -> T?
for example, which would translate any optional input type into an optional output type given a function that translates the base type.
Upvotes: 6
Reputation: 93171
The problem is $0.state = .Flat
is an assignment. It does not return a value. Try this:
wheels = wheels.map { w in
w.state = .Flat
return w
}
map
does not replace anything. It projects each element from your array to a new array by applying the transformation block. You can choose to assign this new array to the old array, but otherwise it will not alter the original array.
Upvotes: 5