【问题标题】:can I split a numeric string using multiple separators in a Swift closure?我可以在 Swift 闭包中使用多个分隔符拆分数字字符串吗?
【发布时间】:2016-12-26 22:17:05
【问题描述】:

我有一个包含小数和小数的字符串数组。

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

每个数组元素都映射在一个闭包中,其中从字符串中提取数字。

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

任一小数(见earlier post

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

或十进制

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

问题:在 Swift 中,有没有一种方法可以使用多个分隔符来拆分字符串,以便单个闭包可以返回小数值或小数值?

(继续关闭)

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

【问题讨论】:

  • 为什么要在小数点处拆分像"193.16" 这样的字符串?您可以直接将其转换为Double
  • 为什么你的字符串数组变量命名为string?这真是令人困惑。
  • @Martin R,正确,只有小数才需要拆分。如果闭包可以识别小数或小数,则对小数进行除法并将"193.16"直接转换为Double,我会非常满意。
  • @rmaddy,点了。我重命名了它。希望 stringArray 更清晰

标签: ios arrays swift closures


【解决方案1】:

由多个分隔符分割

使用split

斯威夫特 4

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

斯威夫特 3

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

斯威夫特 2

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

使用字符集

斯威夫特 4

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

斯威夫特 3

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

斯威夫特 2

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

无论我们使用什么方法,结果你都会收到数组。没有信息,使用了哪个分隔符

如果你只需要将 String 转换为 Double 则

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
}

【讨论】:

  • 你不是说return dividend/divisor.?
  • 对。我的错。谢谢@vacawama
  • @Adrian,return dividends/divisor 工作正常(我仍在检查其余部分)
【解决方案2】:

如果您打算从 无论是十进制表示还是分数,那么就没有 需要在小数点处拆分字符串。

你可以尝试用Double(string)转换字符串, 如果失败,请在斜线处拆分并转换分子 和分母分开:

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
}

(除了返回 nil 无效输入,您还可以 考虑throw 一个错误,中止执行 fatalError(),或者返回一些默认值。)

然后可以将这个“实用函数”应用于每个数组元素:

let strings = [ "0.0", "193.16", "5/4", "503.42", "696.58", "25/16", "1082.89", "2/1"]
let values = strings.flatMap(doubleFromDecimalOrFraction)

【讨论】:

  • 这完全解开了简化问题的问题。这必须是公认的答案。
【解决方案3】:

定义扩展(Swift 4):

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

用法:

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

结果:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 2011-12-26
    • 2023-03-13
    • 1970-01-01
    • 2023-01-07
    • 1970-01-01
    相关资源
    最近更新 更多