Swift:生成一个(Swift)字符数组

时间:2014-10-01 23:47:28

标签: ios xcode string macos swift

简单的问题 - 希望,我正在尝试生成一个简单的字符数组,其中包含以下内容:

// trying to do something like this (pseudo code):
let letters:[Character] = map(0..<26) { i in 'a' + i }

并尝试以下无效

let a = Character("a")
let z = Character("z")
let r:Range<Character> = a..<z
let letters:[Character] = map(a..<z) { i in i }

我意识到Swift使用Unicode,这样做的正确方法是什么?

(注意,这不是关于与遗留Obj-C char互操作的问题,严格来说在Swift中用于测试等)。

11 个答案:

答案 0 :(得分:16)

感谢您提供有用的答案。

我使用的是单行版本。

let xs = (97...122).map({Character(UnicodeScalar($0))})

let xs = (0..<26).map({Character(UnicodeScalar("a".unicodeScalars.first!.value + $0))})

答案 1 :(得分:15)

在Swift中获取初始字符代码(即c / Obj-C中的'a')有点麻烦,但你可以这样做:

let aScalars = "a".unicodeScalars
let aCode = aScalars[aScalars.startIndex].value

let letters: [Character] = (0..<26).map {
    i in Character(UnicodeScalar(aCode + i))
}

答案 2 :(得分:5)

Xcode 10•Swift 4.2

extension ClosedRange where Bound == Unicode.Scalar {
    static let asciiPrintable: ClosedRange = " "..."~"
    var range: ClosedRange<UInt32>  { return lowerBound.value...upperBound.value }
    var scalars: [Unicode.Scalar]   { return range.compactMap(Unicode.Scalar.init) }
    var characters: [Character]     { return scalars.map(Character.init) }
    var string: String              { return String(scalars) }
}

extension String {
    init<S: Sequence>(_ sequence: S) where S.Element == Unicode.Scalar {
        self.init(UnicodeScalarView(sequence))
    }
}

let characters = ("a"..."z").characters  // "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
let string = ("a"..."z").string          // "abcdefghijklmnopqrstuvwxyz"

let range = ClosedRange.asciiPrintable         // {lowerBound " ", upperBound "~"}   32...126
let characters = range.characters  // [" ", "!", """, "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~"]
let string = range.string          // " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

答案 3 :(得分:2)

如果您只想要一个已知集合的数组:

let str = "abcdefghijklmnopqrstuvwxyz"
let characterArray = Array(str)
println(characterArray)

//[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]

答案 4 :(得分:2)

在Swift 5中,您可以使用以下Playground示例代码来从一系列Unicode标量中获取字符数组:

// 1.
let unicodeScalarRange: ClosedRange<Unicode.Scalar> = "A" ... "Z"
// 2.
let unicodeScalarValueRange: ClosedRange<UInt32> = unicodeScalarRange.lowerBound.value ... unicodeScalarRange.upperBound.value
// 3.
let unicodeScalarArray: [Unicode.Scalar] = unicodeScalarValueRange.compactMap(Unicode.Scalar.init)
// 4.
let characterArray: [Character] = unicodeScalarArray.map(Character.init)

print(characterArray)
/*
 prints: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
 */
  1. 创建一系列与大写拉丁字母Unicode块的代码点匹配的Unicode标量。
  2. 由于第一个范围是不可跨越的(您无法对其进行迭代),请使用Unicode.Scalar的{​​{3}} property将其转换为Unicode标量数字表示形式的范围。 / li>
  3. 遍历您的Unicode标量数字表示形式的范围,以创建Unicode标量数组。
  4. 遍历Unicode标量数组以创建字符数组。

或者,如果您需要从Character s范围或String s范围开始,则可以使用以下示例代码之一:

let unicodeScalarRange: ClosedRange<Character> = "A" ... "Z"
let unicodeScalarValueRange = unicodeScalarRange.lowerBound.unicodeScalars[unicodeScalarRange.lowerBound.unicodeScalars.startIndex].value ... unicodeScalarRange.upperBound.unicodeScalars[unicodeScalarRange.lowerBound.unicodeScalars.startIndex].value
let unicodeScalarArray = unicodeScalarValueRange.compactMap(Unicode.Scalar.init)
let characterArray = unicodeScalarArray.map(Character.init)

print(characterArray)
/*
 prints: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
 */
let unicodeScalarRange: ClosedRange<String> = "A" ... "Z"
let unicodeScalarValueRange = unicodeScalarRange.lowerBound.unicodeScalars[unicodeScalarRange.lowerBound.unicodeScalars.startIndex].value ... unicodeScalarRange.upperBound.unicodeScalars[unicodeScalarRange.lowerBound.unicodeScalars.startIndex].value
let unicodeScalarArray = unicodeScalarValueRange.compactMap(Unicode.Scalar.init)
let characterArray = unicodeScalarArray.map(Character.init)

print(characterArray)
/*
 prints: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
 */

答案 5 :(得分:1)

详细信息

swift 4.1,Xcode 9.4.1

解决方案

extension ClosedRange where Bound == String {

    func getAllValues() -> String? {
        guard let upperBound = UnicodeScalar(upperBound), let lowerBound = UnicodeScalar(lowerBound) else {
            return nil
        }
        var result = ""
        var unicodeScalar = lowerBound
        while unicodeScalar != upperBound {
            result += "\(unicodeScalar)"
            guard let us = UnicodeScalar(unicodeScalar.value + 1) else {
                return nil
            }
            unicodeScalar = us
        }
        result += "\(upperBound)"
        return result
    }
}

用法

if let alphabet = ("a"..."z").getAllValues() {
    print("\(alphabet)")
}

答案 6 :(得分:1)

Swift 5,@ Mike S的补丁

    let aScalars = "a".unicodeScalars
    let aCode = aScalars[aScalars.startIndex].value
    
    let letters: [Character] = (0..<26).map {
        i in
        Character(Unicode.Scalar(aCode + i) ?? aScalars[aScalars.startIndex])
    }

答案 7 :(得分:0)

(11 ... 36).map {字符串($ 0-1,基数:$ 0)}

答案 8 :(得分:0)

解决:

// trying to do something like this (pseudo code):
// let letters:[Character] = map(0..<26) { i in 'a' + i }

使用Swift 4.2 / 5.0:

extension Character: Strideable {
    public typealias Stride = Int

    // https://stackoverflow.com/questions/39982335/creating-a-countableclosedrangecharacter
    public func distance(to other: Character) -> Character.Stride {
        let stride = Int(String(self).unicodeScalars.first!.value) - Int(String(other).unicodeScalars.first!.value)
        return abs(stride)
    }

    public func advanced(by n: Character.Stride) -> Character {
        return Character(UnicodeScalar(String(self).unicodeScalars.first!.value + UInt32(n))!)
    }
}

extension ClosedRange where Element == Character {

    var characters: [Character] { return Array(self) }
}

产量:

let letters: [Character] = ("A"..."Z").characters
print(letters)
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

答案 9 :(得分:0)

这是对@Mike S 回答的一个小改进。 您可以简单地获取英文字母表中第一个字符的 ASCII 值并进行如下迭代。

let aScalars = ("a" as Character).asciiValue!

let letters: [Character] = (0..<26).map {
   i in Character(UnicodeScalar(aScalars + i))
}

复杂性

  • 运行时间:O(n)

  • 内存:O(n)

  • 其中 n 是

    中的总字母 (Character)

    英文字母。

答案 10 :(得分:-2)

你可以简单地使用 let alphabets: [UnicodeScalar] = Array("A"..."Z")