How to join array of optional integers to string?

Here's another approach:

[optionalInt1, optionalInt2].flatMap { $0 == nil ? nil : String($0!) }

Edit: You probably shouldn't do this. These approaches are better, to avoid the !

[optionalInt1, optionalInt2].flatMap {
    guard let num = $0 else { return nil }
    return String(num)
}

or:

[optionalInt1, optionalInt2].flatMap { $0.map(String.init) }

You can make use of the map method of Optional within a flatMap closure applied to the array, making use of the fact that the former will return nil without entering the supplied closure in case the optional itself is nil:

let unwrappedStrings = [optionalInt1, optionalInt2]
    .flatMap { $0.map(String.init) }

Also, if you don't wrap the trailing closures (of flatMap, map) in paranthesis and furthermore make use of the fact that the initializer reference String.init will (in this case) non-ambigously resolve to the correct String initializer (as used above), a chained flatMap and map needn't look "bloated", and is also a fully valid approach here (the chained flatMap and map also hold value for semantics).

let unwrappedStrings = [optionalInt1, optionalInt2]
    .flatMap{ $0 }.map(String.init) 

If you don't like the flatMap and the map together you can replace this

[optionalInt1, optionalInt2].flatMap({ $0 }).map({ String($0) })

with this

[optionalInt1, optionalInt2].flatMap { $0?.description }

Wrap up

let optionalInt1: Int? = 1
let optionalInt2: Int? = nil

let result = [optionalInt1, optionalInt2]
    .flatMap { $0?.description }
    .joined(separator: ",")

Update

Since:

  • as @Hamish pointed out direct access to description is discouraged by the Swift team
  • and the OP wants to avoid the flatMap + map concatenation because of the double loop

I propose another solution

let result = [optionalInt1, optionalInt2].flatMap {
        guard let num = $0 else { return nil }
        return String(num)
    }.joined(separator: ",")