一尘不染

有没有一种方法可以从utf16数组快速创建字符串?

swift

我们知道String.utf16提供了代码单位,而String.unicodeScalars提供了标量。

如果我们通过删除一些元素等来操纵codeunits和unicodeScales,是否有办法构造回结果字符串?


阅读 212

收藏
2020-07-07

共1个答案

一尘不染

Swift 2.1更新:

您可以使用StringUTF-16字符数组创建一个

public init(utf16CodeUnits: UnsafePointer<unichar>, count: Int)

初始化程序。例:

let str = "H€llo 😄"

// String to UTF16 array:
let utf16array = Array(str.utf16)
print(utf16array)
// Output: [72, 8364, 108, 108, 111, 32, 55357, 56836]

// UTF16 array to string:
let str2 = String(utf16CodeUnits: utf16array, count: utf16array.count)
print(str2)
// H€llo 😄

先前的答案:

没有任何“内置”(据我所知),但是您可以使用UTF16提供一种decode()方法的结构:

extension String {

    init?(utf16chars:[UInt16]) {
        var str = ""
        var generator = utf16chars.generate()
        var utf16 : UTF16 = UTF16()
        var done = false
        while !done {
            let r = utf16.decode(&generator)
            switch (r) {
            case .EmptyInput:
                done = true
            case let .Result(val):
                str.append(Character(val))
            case .Error:
                return nil
            }
        }
        self = str
    }
}

例:

let str = "H€llo 😄"

// String to UTF16 array:
let utf16array = Array(str.utf16)
print(utf16array)
// Output: [72, 8364, 108, 108, 111, 32, 55357, 56836]

// UTF16 array to string:
if let str2 = String(utf16chars: utf16array) {
    print(str2)
    // Output: H€llo 😄
}

稍微 通用一点 ,您可以定义一个方法,该方法使用给定的编解码器从代码点的数组(或任何序列)创建一个字符串:

extension String {
    init?<S : SequenceType, C : UnicodeCodecType where S.Generator.Element == C.CodeUnit>
        (codeUnits : S, var codec : C) {
        var str = ""
        var generator = codeUnits.generate()
        var done = false
        while !done {
            let r = codec.decode(&generator)
            switch (r) {
            case .EmptyInput:
                done = true
            case let .Result(val):
                str.append(Character(val))
            case .Error:
                return nil
            }
        }
        self = str
    }
}

然后从UTF16转换完成

if let str2a = String(codeUnits: utf16array, codec: UTF16()) {
    print(str2a)
}

这是另一种可能的解决方案。虽然先前的方法是“纯Swift”,但该方法使用Foundation框架以及在NSString和Swift
之间的自动桥接String

extension String {

    init?(utf16chars:[UInt16]) {
        let data = NSData(bytes: utf16chars, length: utf16chars.count * sizeof(UInt16))
        if let ns = NSString(data: data, encoding: NSUTF16LittleEndianStringEncoding) {
            self = ns as String
        } else {
            return nil
        }
    }
}
2020-07-07