Преобразование String в Bool в Swift - через API или самый быстрый подход

Существует ли API для преобразования наиболее возможных строковых представлений логических значений (например, "Истина", "Истина", "Ложное", "ложное", "да", "нет", "1", "0" ) в Bool in Swift?

Если нет, то какой будет самый быстрый подход к кодированию этого с нуля? Будет ли это функциональной картой()? Или что-то еще?

Исходными исходными данными в этом случае являются JSON, но меня интересует суть решения проблемы наиболее вероятным образом и, следовательно, больше узнать о языке в процессе.

+37
источник поделиться
11 ответов

Существует не встроенный AFAIK. Аналогичным методом для стандартного toInt() может быть:

extension String {
    func toBool() -> Bool? {
        switch self {
        case "True", "true", "yes", "1":
            return true
        case "False", "false", "no", "0":
            return false
        default:
            return nil
        }
    }
}
+62
источник

В objective-C у нас есть boolValue для String. Вы можете преобразовать свою строку в NSString, затем использовать ее, если она не существует в Swift

var aString = NSString(string: "tRue")

var b = aString.boolValue

b должен возвращать true, если aString.upperCase == "TRUE"

Обновление: для информации (только в API Apple):

var boolValue: Bool { get } // Skips initial space characters (whitespaceSet), or optional -/+ sign followed by zeroes. Returns YES on encountering one of "Y", "y", "T", "t", or a digit 1-9. It ignores any trailing characters.

Обновление 2: Я провел тест производительности этого метода с помощью метода расширения. Производительность этого метода впечатляет. Вот код моего теста, я назвал эти функции в потоке GCD, используя симулятор, один за другим.

dispatch_async(dispatch_queue_create("com.haduyenhoa.test", nil), {
            self.test1()
            self.test2()
        })


func test1() {
    let testTrue: String = "TRue"
    let testFalse: String = "faLse"

    let testNil: String = "whoops!"

    let begin : NSDate = NSDate()

    NSLog("BEGIN native")
    var testTrueObjC: NSString
    var testFalseObjC : NSString
    var testNilObjC:NSString

    for index in 1...100000 {
        testTrueObjC = NSString(string:testTrue)
         testFalseObjC = NSString(string:testFalse)
        testNilObjC = NSString(string:testNil)

        var b1 = testTrueObjC.boolValue // {Some true}

        var b2 = testFalseObjC.boolValue // {Some false}
        var b3 = testNilObjC.boolValue // nil
    }
    let end : NSDate = NSDate()
    let interval = end.timeIntervalSinceDate(begin)
   NSLog("DURATION native: \(interval)")
}

func test2() {
    let testTrue: String = "TRue"
    let testFalse: String = "faLse"

    let testNil: String = "whoops!"

    let begin : NSDate = NSDate()
    NSLog("BEGIN extension")
    for index in 1...100000 {
        var b1 = testTrue.boolValue() // {Some true}
        var b2 = testFalse.boolValue() // {Some false}
        var b3 = testNil.boolValue() // nil
    }
    let end : NSDate = NSDate()
    let interval = end.timeIntervalSinceDate(begin)
    NSLog("DURATION extension: \(interval)")

}

Журнал консоли:

2015-03-12 14:16:23.238 testSwift3[2343:298787] BEGIN native
2015-03-12 14:16:23.543 testSwift3[2343:298787] DURATION native: 0.305041968822479
2015-03-12 14:16:23.543 testSwift3[2343:298787] BEGIN extension
2015-03-12 14:16:35.360 testSwift3[2343:298787] DURATION extension: 11.8166469931602

Мы можем улучшить производительность решения расширения, упростив правило. Производительность зависит от того, как мы реализуем правило.

+31
источник

Напечатайте вместе с красивым расширением String, и вы запустите

extension String {
var boolValue: Bool {
    return NSString(string: self).boolValue
}}
+19
источник

Используйте это,

self.boolType = NSString(string:stringType!).boolValue
+11
источник

Как уже было сказано, я бы построил расширение до String, указав только строковые литералы, которые вы хотели бы преобразовать в true и false, сохраняя случай nil для того, что не конвертирует (или вернув false в этом случае? Ваш выбор!). Вы, вероятно, не хотите, чтобы ваш метод был чувствительным к регистру, кстати.

Например:

extension String {
    func boolValue() -> Bool? {
        let trueValues = ["true", "yes", "1"]
        let falseValues = ["false", "no", "0"]

        let lowerSelf = self.lowercaseString

        if contains(trueValues, lowerSelf) {
            return true
        } else if contains(falseValues, lowerSelf) {
            return false
        } else {
            return nil
        }
    }
}

let testTrue: String = "TRue"
testTrue.boolValue() // {Some true}
let testFalse: String = "faLse"
testFalse.boolValue() // {Some false}
let testNil: String = "whoops!"
testNil.boolValue() // nil

Будьте осторожны, если вы используете объект NSString и его метод boolValue(), поскольку он возвращает true, если он встречает "Y", "y", "T", "t" или цифру 1- 9 (Смотрите здесь).

В качестве примера:

let nsString = NSString(string: "tFalse")
nsString.boolValue // true
+8
источник
 var st = "false"

 extension String {
   func toBool() -> Bool{
    if self == "false" {
        return false
    }else{
        return true
    }
}
}

 if st.toBool() == false {
     println("its ok")
 }
+2
источник

однострочное решение для необязательной строки

let value:String? = "put some string or even just nil here"
let trueOrFalse = NSString(string: value ?? "").boolValue
0
источник

Я реорганизовал код @Kirsteins как инициализатор Bool со значением String

extension Bool {

    init?(string: String) {
        switch string {
        case "True", "true", "yes", "1":
            self = true
        case "False", "false", "no", "0":
            self = false
        default:
            return nil
        }
    }

}


// tests
let one = Bool(string: "SDASD") // nil
let two = Bool(string: "0") // false
let three = Bool(string: "true") // true
let four = Bool(string: "null") // nil
0
источник

Заключение из вышеприведенных ответов:

Вы можете использовать простую однострочную линию и использовать ее.

Swift 3

extension String {
    func boolValueFromString() -> Bool {
        return NSString(string: self).boolValue
    }
}

Использование

 if (dictCardData.value(forKey: "isadmin") as! String).boolValueFromString() {
    // Stuff
}
0
источник

Если вы используете один раз, попробуйте это.

let str:String = "1"

var boo:Bool = str == "1" || str == "true" || str == "True" || str == "yes"
0
источник

Я предпочитаю эту реализацию, которая обрабатывает необязательные строки и имеет значение по умолчанию false

extension Bool {
    init(_ string: String?) {
        guard let string = string else { self = false; return }

        switch string.lowercased() {
        case "true", "yes", "1":
            self = true
        default:
            self = false
        }
    }
}
0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос