66

Given a Bool?, I'd like to be able to do this:

let a = BoolToString(optbool) ?? "<None>"

which would either give me "true", "false", or "<None>".

Is there a built-in for BoolToString?

2
  • And you would want the true, false, and <None> to be strings? Commented Nov 22, 2015 at 22:02
  • @dannybess Sorry, missed that. Yes. Commented Nov 22, 2015 at 22:03

6 Answers 6

79

String(Bool) is the easiest way.

var myBool = true
var boolAsString = String(myBool)
Sign up to request clarification or add additional context in comments.

Comments

63
let b1: Bool? = true
let b2: Bool? = false
let b3: Bool? = nil

print(b1?.description ?? "none") // "true"
print(b2?.description ?? "none") // "false"
print(b3?.description ?? "none") // "none"

or you can define 'one liner' which works with both Bool and Bool? as a function

func BoolToString(b: Bool?)->String { return b?.description ?? "<None>"}

3 Comments

Change "none" to "<None>". I think we have a winner here! :-)
That's not quite orthodox Swift programming, the conventions of conversion via type initializers is one of prominent feature of all data conversion APIs. However, CustomStringConvertible, which declares description is an API that semantically is supposed to be used not for data serialization but debugging purposes. You should always use String.init(_:) instead.
@IsaaсWeisberg is certainly right. The documentation for description discourages calling it directly. developer.apple.com/documentation/swift/customstringconvertible
27
let trueString = String(true) //"true"
let trueBool = Bool("true")   //true
let falseBool = Bool("false") //false
let nilBool = Bool("foo")     //nil

Comments

8

You could use the ?: ternary operator:

let a = optBool == nil ? "<None>" : "\(optBool!)"

Or you could use map:

let a = optBool.map { "\($0)" } ?? "<None>"

Of the two, optBool.map { "\($0)" } does exactly what you want BoolToString to do; it returns a String? that is Optional(true), Optional(false), or nil. Then the nil coalescing operator ?? unwraps that or replaces nil with "<None>".

Update:

This can also be written as:

let a = optBool.map(String.init) ?? "<None>"

or:

let a = optBool.map { String($0) } ?? "<None>"

Comments

4
var boolValue: Bool? = nil
var stringValue = "\(boolValue)" // can be either "true", "false", or "nil"

Or a more verbose custom function:

func boolToString(value: Bool?) -> String {
    if let value = value {
        return "\(value)"
    }
    else { 
        return "<None>"
        // or you may return nil here. The return type would have to be String? in that case.
    }

}

2 Comments

So, no? There is no built-in way?
This defers to CustomStringConvertible i.e. the same solution as accepted answer.
1

You can do it with extensions!

extension Optional where Wrapped == Bool {
  func toString(_ nilString: String = "nil") -> String {
    self.map { String($0) } ?? nilString
  }
}

Usage:

let b1: Bool? = true
let b2: Bool? = false
let b3: Bool? = nil

b1.toString() // "true"
b2.toString() // "false"

b3.toString() // "nil"
b3.toString("<None>") // "<None>"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.