You can use map() with an if-condition inside the closure:
var arr = [11, 12, 13, 14, 15]
arr = arr.map { elem in
if elem == 15 { return 1 } else { return 0 }
}
print(arr) // [0, 0, 0, 0, 1]
Using the conditional operator ?: and closure shorthand notation $0,
this can be simplified to
arr = arr.map { $0 == 15 ? 1 : 0 }
map() calls the closure with each element in turn,
and returns an array with the closure return values.
Inside the closure, $0 is the current argument, and the return value
is 1 or 0, depending on the boolean condition.
Another way to solve it is to use reduce
let strippedName = data.reduce(into: []) { if $1.1 == "a" {$0.append($1.1)}}
Update
Trying to solve this as OP wants by using an if in the mapping. For my example here I use compactMap rather than map, this way anything that doesn't satisfy the if condition will be excluded from the array.
Since the return type of the closure is define to be String I don't need to do a second mapping
let strippedName = data.compactMap { t -> String? in
if t.1 == "a" {
return t.1
}
return nil
}
Swift could not infer the complex closure return type, hence it is showing you the error "Ambiguous use of init()"
Specifying the return type explicitly solves the issue.
let data: [(String?, String)] = [("a","bBCDEA"), ("b","a"), (nil,"CBCDEB"), ("d","aBCDEF"), (nil,"a"), ("f","FBCDEC")]
var strippedName = (data.map { tuple -> String.Element in
if (tuple.1 == "a") {
return tuple.1.first!
} else {
return tuple.1.last!
}
}).map{ String($0) }
print(strippedName) // ["A", "a", "B", "F", "a", "C"]
strippedName = (data.map{ ($0.1).dropLast(5) } ).map{ String($0) }
print(strippedName) // ["b", "", "C", "a", "", "F"]
What is the difference between CompactMap and map Swift?
What is the difference between map and filter in Swift?
Is filter faster than for loop Swift?
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.
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.