在Swift中,将单个字符的字符串转换为ASCII值的最简单方法是什么?

87
我只想在Swift中获取单个字符字符串的ASCII值。目前,我正在这样做:
var singleChar = "a"
println(singleChar.unicodeScalars[singleChar.unicodeScalars.startIndex].value) //prints: 97

虽然这样很丑,但一定有更简单的方法。

15个回答

144

编辑/更新Swift 5.2或更高版本

extension StringProtocol {
    var asciiValues: [UInt8] { compactMap(\.asciiValue) }
}

"abc".asciiValues  // [97, 98, 99]
在 Swift 5 中,您可以使用新的字符属性 isASCIIasciiValue
Character("a").isASCII       // true
Character("a").asciiValue    // 97

Character("á").isASCII       // false
Character("á").asciiValue    // nil

旧回答

你可以创建一个扩展:

Swift 4.2 或更高版本

extension Character {
    var isAscii: Bool {
        return unicodeScalars.allSatisfy { $0.isASCII }
    }
    var ascii: UInt32? {
        return isAscii ? unicodeScalars.first?.value : nil
    }
}

extension StringProtocol {
    var asciiValues: [UInt32] {
        return compactMap { $0.ascii }
    }
}

Character("a").isAscii  // true
Character("a").ascii    // 97

Character("á").isAscii  // false
Character("á").ascii    // nil

"abc".asciiValues            // [97, 98, 99]
"abc".asciiValues[0]         // 97
"abc".asciiValues[1]         // 98
"abc".asciiValues[2]         // 99

15
UnicodeScalar("1")!.value // returns 49

Swift 3.1


@ixany 强制解包是有原因的,而且在这种情况下,我们有101%的把握初始化程序不会失败("1"是有效字符)。 - Cristik
@Cristik 不同意。一般来说,你不能确定输入值不会永远失败。那么为什么不保险点呢?更好的方法是:guard let value = UnicodeScalar("1")?.value else { return } - ixany
@ixany,你不同意“1”是一个有效的字符吗? :) - Cristik
@Cristik,“if let”或“guard let”语句也有存在的理由。我深信,尽可能地保险起见是明智之举。作为经验更加丰富的开发人员,我们应该为这里所有新手提供良好的代码风格和最佳实践。这并不是针对任何人的冒犯之意。 - ixany
@ixany,是的,我同意,我自己尽可能避免强制解包,但是有时候(很少或非常少)使用强制解包是有意义的。在回答上下文中,“从不是一个好主意”对我来说有点过于极端了,这就是为什么我回复的原因 :) - Cristik

11

现在在Xcode 7.1和Swift 2.1中

var singleChar = "a"

singleChar.unicodeScalars.first?.value

10
你可以使用NSString的characterAtIndex来完成这个任务...
var singleCharString = "a" as NSString
var singleCharValue = singleCharString.characterAtIndex(0)
println("The value of \(singleCharString) is \(singleCharValue)")  // The value of a is 97

1
@vacawama,我在使用Swift 4时遇到了错误error: value of type 'String' has no member 'character'。但是当我将"a"作为NSString使用时,它可以工作 :) - Kamaldeep singh Bhatia

8

Swift 4.2

以下是从Swift字符串获取ASCII值的最简单方法:

let str = "Swift string"
for ascii in str.utf8 {
    print(ascii)
}

输出:

83
119
105
102
116
32
115
116
114
105
110
103

这不是ASCII值。它将返回一个字节数组。非ASCII字符将返回多个字节,与ASCII表无关。 - Leo Dabus
1
尝试 let str = "" for ascii in str.utf8 { print(ascii) } // 240, 159, 152, 128 - Leo Dabus

3
这是我的实现,它返回ASCII值的数组。
extension String {

    func asciiValueOfString() -> [UInt32] {

      var retVal = [UInt32]()
      for val in self.unicodeScalars where val.isASCII() {
          retVal.append(UInt32(val))
      }
      return retVal
    }
}

注意:它是兼容Swift 2的。

3

Swift 4.1

https://oleb.net/blog/2017/11/swift-4-strings/

本文主要介绍了Swift 4.1中字符串的新功能,包括可编译的常量和变量字符串插值,Unicode 10支持以及新的API。对于开发人员来说,这些改进可以使他们更轻松地处理字符串,并将其集成到现有项目中。详细的介绍请参阅上述链接。
let flags = "99_problems"
flags.unicodeScalars.map {
    "\(String($0.value, radix: 16, uppercase: true))"
}

结果:

["39", "39", "5F", "70", "72", "6F", "62", "6C", "65", "6D", "73"]

这是一个包含十六进制数的数组。

尝试 let flags = "" flags.unicodeScalars.map { "\(String($0.value, radix: 16, uppercase: true))" } // "1F600" - Leo Dabus

3

您现在的做法是正确的。如果您不喜欢索引的冗长,可以通过循环Unicode标量来避免它:

var x : UInt32 = 0
let char = "a"
for sc in char.unicodeScalars {x = sc.value; break}

在这种情况下,你可以省略break,因为只有一个 Unicode scalar。
或者,将其转换为数组并使用Int索引(绝望的最后手段):
let char = "a"
let x = Array(char.unicodeScalars)[0].value

3
这个可以稍微缩短一点的写法是:
first(singleChar.unicodeScalars)!.value

与下标版本一样,如果您的字符串实际上为空,则会崩溃,因此如果您不确定,请使用可选项:
if let ascii = first(singleChar.unicodeScalars)?.value {

}

或者,如果你想要更加谨慎,

if let char = first(singleChar.unicodeScalars) where char.isASCII() {
    let ascii = char.value
}

2

Swift 4+

字符转ASCII码

let charVal = String(ch).unicodeScalars
var asciiVal = charVal[charVal.startIndex].value

ASCII 转换为字符

let char = Character(UnicodeScalar(asciiVal)!)

尝试 let charVal = String("").unicodeScalars charVal[charVal.startIndex].value // 128512 - Leo Dabus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接