在Swift中将字符加/减为Int

时间:2017-07-18 20:14:37

标签: swift string character

我需要实现一个算法,通过计算String的模数来检查输入是否有效。

Kotlin中的代码:

private val facteurs = arrayOf(7, 3, 1)

private fun modulo(s: String): Int {
    var result = 0
    var i = -1
    var idx = 0
    for (c in s.toUpperCase()) {
        val value:Int
        if (c == '<') {
            value = 0
        } else if (c in "0123456789") {
            value = c - '0'
        } else if (c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ") {
            value = c.toInt() - 55
        } else {
            throw IllegalArgumentException("Unexpected character: $c at position $idx")
        }
        i += 1
        result += value * facteurs[i % 3]
        idx += 1
    }
    return result % 10
}

这意味着对角色进行数学运算。

在Swift 3和4中有优雅的方法吗?

我尝试了一些像这样繁琐的构造:

value = Int(c.unicodeScalars) - Int("0".first!.unicodeScalars)

但它甚至没有编译。 我目前正在使用Swift 4和XCode9,但也欢迎Swift3的回答。

2 个答案:

答案 0 :(得分:3)

您可以一起枚举字符串的unicodeScalars视图 使用运行索引,使用开关/案例模式匹配, 并访问unicode标量的数字.value

func modulo(_ s: String) -> Int? {
    let facteurs = [7, 3, 1]
    var result = 0
    for (idx, uc) in s.uppercased().unicodeScalars.enumerated() {
        let value: UInt32
        switch uc {
        case "<":
            value = 0
        case "0"..."9":
            value = uc.value - UnicodeScalar("0").value
        case "A"..."Z":
            value = uc.value - UnicodeScalar("A").value + 10
        default:
            return nil
        }
        result += Int(value) * facteurs[idx % facteurs.count]
    }
    return result % 10
}

这适用于Swift 3和4.当然你也可以 throw错误,而不是为无效输入返回nil

请注意"<""0""9"等。 在switch语句中从上下文推断为UnicodeScalar, 不是StringCharacter,因此"0"..."9"(在此上下文中) 是ClosedRange<UnicodeScalar>uc可以匹配 那范围。

答案 1 :(得分:1)

这样的事情对我有用:

"A".utf16.first! + 2 //comes out to 67

小心强行打开“!”

如果你需要scalars值,你可以做

"A".unicodeScalars.first!.value + 2

可以对此here in the SPL进行更多阅读。

对于c字符类型值,您可以执行以下操作:

String(c).unicodeScalars.first!.value + 2

这是尝试修改函数:

func modulo(s: String) -> Int? {
var result = 0
var factors = [7,3,1]
for (i, c) in s.uppercased().characters.enumerated() {
    let char = String(c)
    var val: Int
    if char == "<" {
        val = 0
    } else if "0123456789".contains(char) {
        val = Int(char.unicodeScalars.first!.value - "0".unicodeScalars.first!.value)
    } else if "ABCDEFGHIJKLMNOPQRSTUVWXYZ".contains(char) {
        val = Int(char.unicodeScalars.first!.value - 55)
    } else {
        return nil
    }

       result += val * factors[(i) % 3]
    }

    return result % 10
}

这是快速3 ... 4我相信你可以迭代字符串而不转换为Chars