86

Basic way doesn't work.

for index in 0 ..< list.count {
    if list[index] == nil {
        list.removeAtIndex(index) //this will cause array index out of range
    }
}
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080
  • Possible duplicate of [Swift: shortcut unwrapping of array of optionals](http://stackoverflow.com/questions/25589605/swift-shortcut-unwrapping-of-array-of-optionals) – Senseful Jul 24 '16 at 00:31

4 Answers4

189

The problem with your code is that 0 ..< list.count is executed once at the beginning of the loop, when list still has all of its elements. Each time you remove one element, list.count is decremented, but the iteration range is not modified. You end up reading too far.

In Swift 4.1 and above, you can use compactMap to discard the nil elements of a sequence. compactMap returns an array of non-optional values.

let list: [Foo?] = ...
let nonNilElements = list.compactMap { $0 }

If you still want an array of optionals, you can use filter to remove nil elements:

list = list.filter { $0 != nil }
zneak
  • 134,922
  • 42
  • 253
  • 328
76

In Swift 2.0 you can use flatMap:

list.flatMap { $0 }
Marcel Molina
  • 994
  • 6
  • 6
  • This also has the added benefit of not requiring the objects in the list to be Equatable. – Tim Feb 17 '16 at 03:03
  • 1
    Now that we have it, this is a better solution. – zneak Apr 04 '16 at 18:25
  • 9
    Relying on `flatMap { $0 }` to remove nils can lead to bugs. Use an [extension method like `removeNils()` instead](http://stackoverflow.com/a/38548106/35690). – Senseful Jul 26 '16 at 06:32
47

Now in swift 4.2 you can use

list.compactMap{ $0 }

list.flatMap{ $0 } is already deprecated.

pkamb
  • 33,281
  • 23
  • 160
  • 191
kalafun
  • 3,512
  • 6
  • 35
  • 49
2

A much elegant solution would be to use compacted() defined in the Algorithms package made by Apple itself.

import Algorithms

let array = [10, nil, 20, nil, 30]
print(array.compacted()) // prints [10, 20, 30]

Benefits

  1. Concise
  2. Filters out nil items lazily

More info https://github.com/apple/swift-algorithms/blob/main/Guides/Compacted.md

Kaunteya
  • 3,107
  • 1
  • 35
  • 66