William Hu
William Hu

Reputation: 16189

Swift convert [String?] to [String!]

I tested in Swift 3.0. I want to add array1 to array2, example and errors as below:

var array1: [String?] = ["good", "bad"]
var array2 = [String!]()

array2.append(array1)
//Cannot convert value of type '[String?]' to expected argument type 'String!'
array2.append(contentsOf: array1)
//Extraneous argument label 'contentsOf:'in call

I know if I change to

var array2 = [String?]()
array2.append(contentsOf: array1)

it works! How should I fix this if i don't change type?

Upvotes: 1

Views: 1856

Answers (2)

Luca Angeletti
Luca Angeletti

Reputation: 59536

In Swift 3 you cannot define an array where the generic element is an implicitly unwrapped optional.

Implicitly unwrapped optionals are only allowed at top level and as function results.

The compiler

What you can do is creating a new array of String containing only the populated elements of array1.

let array1: [String?] = ["good", "bad", nil]
let array2: [String] = array1.flatMap { $0 }

print(array2) // ["good", "bad"]

Update

As shown by Sam M this is indeed possible, here's the code

let array2 = array1.map { elm -> String! in
    let res: String! = elm
    return res
}

Upvotes: 3

Vince O'Sullivan
Vince O'Sullivan

Reputation: 2701

var array1: [String?] = ["good", "bad"]
var array2 = [String!]()
var array2a = [String]()

for item in array1 {
    array2.append(item)
}
for item in array1 {
    array2a.append(item!)
}
print("1", array1)
print("2", array2)
print("2a", array2a)

Prints:

1 [Optional("good"), Optional("bad")]

2 [good, bad]

2a ["good", "bad"]

Mapping also works, e.g.:

array2 = array1.map{ $0 }
array2a = array1.filter{ $0 != nil }.map{ $0! }

Upvotes: 1

Related Questions