user1107173 user1107173 - 1 year ago 60
Swift Question

Swift: Avoid imperative For Loop

What I'm trying to accomplish in imperative:

var mapNames = [String]()
var mapLocation = [String]()

for valueMap in valueMaps {
if let name = {
if let location = valueMap.location {

What's the best way using a high order function or perhaps an array method (
etc.) to compact the code above and also avoid using the

Here is what I have tried, but the compiler gives an error:

let getArrayOfNames = valueMaps.filter() {
if let name = ($0 as valueMaps).name as [String]! {
return name;

let getArrayOfLocations = valueMaps.filter() {
if let type = ($0 as valueMaps).location as [String]! {
return type;

Answer Source

You need both filter() and map() :

let mapNames = valueMaps.filter( {$ != nil }).map( { $! })
let mapLocations = valueMaps.filter( {$0.location != nil }).map( { $0.location! })

The filter takes a predicate as an argument (which specifies which elements should be included in the result), and the map takes a transformation as an argument. You were trying to merge both aspects into the filter, which is not possible.

Update: As of Swift 2(?) has a flatMap() method for sequences, which can be used to obtain the result in a single step:

let mapNames = valueMaps.flatMap { $ }

The closure is applied to all array elements, and the return value is an array with all non-nil unwrapped results.