Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleaner way to filter nil in Swift array [duplicate]

Tags:

ios

swift

Let's say I have a Swift object called Animal. I have an array of Animal objects, some of which could be nil.

Currently I'm doing this:

arrayOfAnimal.filter({$0 != nil}) as! [Animal]

This feels rather hacky because of the force unwrapping. Wondering if there's a better way to filter out nils.

like image 535
7ball Avatar asked Dec 15 '17 19:12

7ball


2 Answers

flatMap() does the job:

let filtered = arrayOfAnimal.flatMap { $0 }

The closure (which is the identity here) is applied to all elements, and an array with the non-nil results is returned. The return type is [Animal] and no forced cast is needed.

Simple example:

let array: [Int?] = [1, nil, 2, nil, 3]
let filtered = array.flatMap { $0 }

print(filtered)            // [1, 2, 3]
print(type(of: filtered))  // Array<Int>

For Swift 4.1 and later, replace flatMap by compactMap.

like image 171
Martin R Avatar answered Nov 03 '22 09:11

Martin R


Your code works, but there is a better way. Use the compactMap function.

struct Animal {}

let arrayOfAnimal: [Animal?] = [nil, Animal(), Animal(), nil]
let newArray: [Animal] = arrayOfAnimal.compactMap { $0 }
like image 14
picciano Avatar answered Nov 03 '22 09:11

picciano