Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to join array of optional integers to string?

Given [Int?], need to build string from it.

This code snippet works

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

    let unwrappedStrings = [optionalInt1, optionalInt2].flatMap({ $0 }).map({ String($0) })
    let string = unwrappedStrings.joined(separator: ",")

But I don't like flatMap followed by map. Is there any better solution?

like image 587
Yakiv Kovalskyi Avatar asked Jan 05 '17 15:01

Yakiv Kovalskyi


2 Answers

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) }
like image 154
Alexander Avatar answered Sep 20 '22 06:09

Alexander


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) 
like image 36
dfrib Avatar answered Sep 22 '22 06:09

dfrib