The other answers use flatMap to eliminate the nil elements and require a call to joined() to combine the elements and add the commas.
Using joined() to add the commas is of course a second pass through the
array. Here's a way to use reduce to do this in one pass:
let arr: [Int?] = [nil, nil, 1, 2, 3, nil, 4, nil, 5, nil]
let result = arr.reduce("") { $1 == nil ? $0 : $0.isEmpty ? "\($1!)" : $0 + ",\($1!)" }
print(result)
Output:
1,2,3,4,5
Explanation
This example uses reduce to construct the result string element by element.
reduce is a method called on a sequence. It takes an initial value ("" in this example) and a closure that combines the next element in the sequence with the partial result to create the next partial result.
The closure is called on each element in the sequence (i.e. array arr). The closure first checks if the element is nil and if it is, it returns the partial result unmodified. If the element is not nil, it then checks if the partial result is still the empty string. If it is empty, this is the first element in the result so it returns a string made up of just the element. If the partial result is not empty, it adds the new element preceded by a , to the partial result.
Use reduce(into:):
Rewriting this to use reduce(into:) and append results in an implementation that is twice as fast as the other answers when generating the final comma separated string.
let result = arr.reduce(into: "") { (string, elem) in
guard let elem = elem else { return }
if string.isEmpty {
string = String(elem)
} else {
string.append(",\(elem)")
}
}