can I split a numeric string using multiple separators in a Swift closure?

前端 未结 3 1580
面向向阳花
面向向阳花 2020-12-07 05:13

I have a string array with fractional numbers and decimal numbers.

    let stringArray = [ \"0.0\", \"193.16\", \"5/4\", \"503.42\", \"696.58\", \"25/16\", \         


        
相关标签:
3条回答
  • 2020-12-07 05:49

    If your intention is to create floating point numbers from either a decimal representation or a fraction, then there is no need to split the string at the decimal point.

    You can try to convert the string with Double(string), and if that fails, split it at the slash and convert numerator and denominator separately:

    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
    }
    

    (Instead of returning nil for invalid input you might also consider to throw an error, to abort the execution with fatalError(), or to return some default value.)

    This "utility function" can then be applied each array element:

    let strings = [ "0.0", "193.16", "5/4", "503.42", "696.58", "25/16", "1082.89", "2/1"]
    let values = strings.flatMap(doubleFromDecimalOrFraction)
    
    0 讨论(0)
  • 2020-12-07 05:53

    Define extension (Swift 4):

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

    Usage:

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

    Result :

    ["aaa", "bbb", "ccc", "ffffd"]

    0 讨论(0)
  • 2020-12-07 06:09

    Split by more than one separator

    Using 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) }
    

    Swift 2

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

    Using characterSet

    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)
    

    Swift 2

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

    No matter what method we will use, and as a result, you will receive array. Without the information, which separator was used

    If you need only convert String to Double then

    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
    }
    
    0 讨论(0)
提交回复
热议问题