Convierta String a Bool en Swift-a través de API o la mayoría del enfoque similar a Swift
boolean (13)
¿Existe una API para convertir la mayoría de las representaciones de cadena posibles de valores booleanos (por ejemplo, "True", "true", "False", "false", "yes", "no", "1", "0") en Bool? en Swift?
Si no, ¿cuál sería el enfoque más rápido para codificar esto desde cero? ¿Sería una operación map () funcional? ¿O algo mas?
La fuente de datos original en este caso es JSON, pero estoy interesado en el quid de resolver el problema de la manera más rápida posible y, por lo tanto, aprender más sobre el lenguaje en el proceso.
Como ya se sugirió, construiría una extensión para
String
, enumerando solo los literales de cadena que le gustaría convertir en
true
y
false
, manteniendo un caso
nil
para lo que no convierte (¿o devolviendo
false
en ese caso? ¡Su elección! )
Probablemente no quieras que tu método distinga entre mayúsculas y minúsculas, por cierto.
Por ejemplo:
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
Tenga cuidado si usa un objeto
NSString
y su método
boolValue()
, ya que devuelve
true
si encuentra "Y", "y", "T", "t" o un dígito 1-9 (
consulte los documentos aquí
).
Como ejemplo:
let nsString = NSString(string: "tFalse")
nsString.boolValue // true
Conclusión de las respuestas anteriores:
Puede corregir la extensión y el uso de una sola línea.
Swift 3
if (dictCardData.value(forKey: "isadmin") as! String).boolValueFromString() {
// Stuff
}
Uso
var st = "false"
extension String {
func toBool() -> Bool{
if self == "false" {
return false
}else{
return true
}
}
}
if st.toBool() == false {
println("its ok")
}
En el objetivo C, tenemos boolValue para una cadena. Puede convertir su cadena a NSString y luego usarla, si no existe en Swift
var aString = NSString(string: "tRue")
var b = aString.boolValue
b debería devolver verdadero si aString.upperCase == "TRUE"
Actualización: para información (recién visto en la API de 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.
Actualización 2: hice una prueba de rendimiento de este método con el método de extensión. El rendimiento de este método es impresionante. Aquí está el código de mi prueba, he llamado a estas funciones en un hilo GCD, usando el simulador, uno tras otro.
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)")
}
El registro de la consola:
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
Podemos mejorar el rendimiento de la solución de extensión simplificando la regla. El rendimiento depende de cómo implementemos la regla.
Ninguna otra respuesta se ocupa del potencial de cadenas de mayúsculas completas o mixtas. Entonces, ¿por qué no tomar la respuesta de Kirsteins, mezclarla con alguna propiedad mágica calculada y shazam:
let trueBoolString = "TRUE" // or "True", "true", "YES", "yEs", and so on
print(trueBoolString.bool) // true
El uso sería:
extension String {
var boolValue: Bool {
return (self as NSString).boolValue
}
}
No está construido en modo AFAIK.
Un método similar al estándar
toInt()
podría ser:
extension String {
var bool: Bool? {
switch self.lowercased() {
case "true", "t", "yes", "y", "1":
return true
case "false", "f", "no", "n", "0":
return false
default:
return nil
}
}
}
Prefiero esta implementación que maneja cadenas opcionales y tiene un valor predeterminado de falso
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
}
}
}
Refactoré el código de @Kirsteins como inicializador Bool con valor de cadena
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
Si usa una vez, intente esto.
let str:String = "1"
var boo:Bool = str == "1" || str == "true" || str == "True" || str == "yes"
Tipografía junto con una buena extensión de cadena y ya está en funcionamiento
extension String {
var boolValue: Bool {
return NSString(string: self).boolValue
}}
Tomé la solución de Nicolas Manzini y la modifiqué un poco. Recomiendo usar el operador de conversión porque está puenteado entre String y NSString. Se desconoce si es un puente gratuito, pero debería tener un mejor rendimiento que crear un nuevo objeto a ciegas.
extension String {
func boolValueFromString() -> Bool {
return NSString(string: self).boolValue
}
}
Utilizar este,
self.boolType = NSString(string:stringType!).boolValue
solución de una línea para cadena opcional
let value:String? = "put some string or even just nil here"
let trueOrFalse = NSString(string: value ?? "").boolValue
extension String {
var bool: Bool? {
let lowercaseSelf = self.lowercased()
switch lowercaseSelf {
case "true", "yes", "1":
return true
case "false", "no", "0":
return false
default:
return nil
}
}
}