Tengo una serie de cadenas con números fraccionarios y números decimales.

    let stringArray = [ "0.0", "193.16", "5/4", "503.42", "696.58", "25/16", "1082.89", "2/1"]

Cada elemento de la matriz se mapea en un cierre donde los números se extraen de la cadena.

    let values = stringArray.map { s -> Double in

ya sea fraccional (consulte publicación anterior)

    let splitStrings = s.characters.split(separator: "/").map(String.init).map({ Double($0) })

o decimal

    let splitStrings = s.characters.split(separator: ".").map(String.init).map({ Double($0) })

Pregunta : en Swift, ¿hay alguna manera de dividir la cadena con más de un separador para que un cierre único pueda devolver valores fraccionales o decimales?

(continuación del cierre)

switch (token)) {
case "/"  :
        print( "fraction")

        let pathA = splitString[0]!/splitString[1]!
        return pathA

case "."  :
        print( "decimal")

        let upperSplit = splitString[0]!
        let lowerSplit = splitString[1]! * 0.1  // restore decimal point
        let pathB = upperSplit+lowerSplit
        return pathB
        }
}
1
Greg 27 dic. 2016 a las 01:17

3 respuestas

La mejor respuesta

Si su intención es crear números de coma flotante a partir de una representación decimal o una fracción, entonces no hay necesidad de dividir la cadena en el punto decimal.

Puedes intentar convertir la cadena con Double(string), y si eso falla, divídalo en la barra inclinada y convierta el numerador y denominador por separado:

func doubleFromDecimalOrFraction(s: String) -> Double? {
    // Try to convert from decimal representation:
    if let value = Double(s) {
        return value
    }
    // Try to convert from fractional format:
    if let range = s.range(of: "/"),
        let num = Double(s.substring(to: range.lowerBound)),
        let den = Double(s.substring(from: range.upperBound)) {
        return num/den
    }
    // Invalid format
    return nil
}

(En lugar de devolver nil para una entrada no válida, también puede considere throw un error, para abortar la ejecución con fatalError(), o para devolver algún valor predeterminado).

Esta "función de utilidad" se puede aplicar a cada elemento de la matriz:

let strings = [ "0.0", "193.16", "5/4", "503.42", "696.58", "25/16", "1082.89", "2/1"]
let values = strings.flatMap(doubleFromDecimalOrFraction)
3
Martin R 26 dic. 2016 a las 22:59

Definir extensión (Swift 4):

extension String {
    func split(separators: String) -> [String] {
        return components(separatedBy: CharacterSet(charactersIn: separators))
    }
}

Uso:

let str = "aaa-bbb_ccc/ddd"
let arr = str.split(separators: "-_/")

Resultado:

["aaa", "bbb", "ccc", "ddd"]

0
Joey 24 dic. 2018 a las 01:55

Dividida por más de un separador

Usando split

Swift 4

let s = "[0, 1, 2, 1]"
let splitted = s.characters.split { [",", "[", "]"].contains($0.description) }

Swift 3

let s = "[0, 1, 2, 1]"
let splitted = s.characters.split { [",", "[", "]"].contains($0.description) }

Rápida 2

let s = "[0, 1, 2, 1]"
let splitted = s.characters.split(isSeparator: {[",", "[", "]"].contains($0)}) }

Usando juego de caracteres

Swift 4

let str = "[0, 1, 2, 1]"
let separatorSet = CharacterSet(charactersIn: ",[]")
let comps = str.components(separatedBy: separatorSet)

Swift 3

let str = "[0, 1, 2, 1]"
let separatorSet = CharacterSet(charactersInString: ",[]")
let comps = str.components(separatedBy: separatorSet)

Rápida 2

let str = "[0, 1, 2, 1]"
let separatorSet = NSCharacterSet(charactersInString: ",[]")
let comps = str.componentsSeparatedByCharactersInSet(separatorSet)

No importa qué método usaremos y, como resultado, recibirá una matriz. Sin la información, qué separador se utilizó

Si solo necesita convertir String a Double, entonces

let array = stringArray.compactMap { element -> Double? in
    if let value = Double(element) {
        return value
    }
    let parts = element.components(separatedBy: "/")
    guard parts.count == 2, 
          let dividend = Double(parts[0]), 
          let divisor = Double(parts[1]), 
          divisor != 0
    else {
        return nil
    }
    return dividend / divisor
}
7
Ryan Heitner 1 dic. 2018 a las 12:51