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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26152448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:45:37  来源:igfitidea点击:

Swift: generate an array of (Swift) characters

iosxcodestringmacosswift

提问by Chris Conover

Simple question - hopefully, I am trying to generate a simple array of characters, something in the vein of:

简单的问题 - 希望我正在尝试生成一个简单的字符数组,大致如下:

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

and have tried the following to no avail

并尝试了以下无济于事

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

I realize that Swift uses Unicode, what is the correct way to do something like this?

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

(Note, this is not a question about interop with legacy Obj-C char, strictly in Swift for testing etc).

(注意,这不是与遗留 Obj-C 字符互操作的问题,严格在 Swift 中进行测试等)。

回答by Mike S

It's a little cumbersome to get the initial character code (i.e. 'a'in c / Obj-C) in Swift, but you can do it like this:

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

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

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

回答by Daishi Nakajima

Thanks for useful answers.

感谢您提供有用的答案。

I'm using one-liner version.

我正在使用单线版本。

let xs = (97...122).map({Character(UnicodeScalar(
let xs = (0..<26).map({Character(UnicodeScalar("a".unicodeScalars.first!.value + 
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) }
}
))})
))})

or

或者

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

回答by Leo Dabus

Xcode 10 ? Swift 4.2

Xcode 10?斯威夫特 4.2

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{|}~"


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]


// 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"]
 */

回答by Steve Rosenberg

If you just want an array of a known set:

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

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"]
 */

回答by Imanou Petit

With Swift 5, you can use the following Playground sample code in order to get an array of characters from a range of Unicode scalars:

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

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"]
 */
  1. Create a range of Unicode scalars that match the code points for uppercased latin alphabet Unicode block.
  2. Because this first range is not strideable (you can't iterate on it), convert it to a range of Unicode scalar numeric representations using Unicode.Scalar's valueproperty.
  3. Iterate over your range of Unicode scalar numeric representations in order to create an array of Unicode scalars.
  4. Iterate over your array of Unicode scalars in order to create an array of characters.
  1. 创建一系列与大写拉丁字母 Unicode 块的代码点匹配的 Unicode 标量。
  2. 因为第一个范围是不可跨越的(您不能对其进行迭代),所以使用Unicode.Scalar's将其转换为一系列 Unicode 标量数字表示。valueproperty
  3. 迭代您的 Unicode 标量数字表示范围,以创建 Unicode 标量数组。
  4. 迭代您的 Unicode 标量数组以创建字符数组。


As an alternative, you can use one of the sample codes below if you need to start from a range of Characters or a range of Strings:

作为替代方案,如果您需要从Characters 范围或 s范围开始,您可以使用以下示例代码之一String

// MAKR: - ClosedRange extensions

extension ClosedRange where Bound == Unicode.Scalar {
    var representationRange: ClosedRange<UInt32> { return lowerBound.value...upperBound.value }
    var scalars: [Bound] { return representationRange.compactMap(Bound.init) }
}

extension ClosedRange where Bound == Character {
    var scalars: [Unicode.Scalar]? {
        guard lowerBound.unicodeScalars.count == 1, upperBound.unicodeScalars.count == 1 else { return nil }
        return (lowerBound.unicodeScalars.first! ... upperBound.unicodeScalars.first!).scalars
    }
    var all: [Bound]? { return scalars?.map(Character.init) }
}

extension ClosedRange where Bound == String  {
    var scalars: [Unicode.Scalar]? {
        guard   lowerBound.unicodeScalars.count == 1, upperBound.unicodeScalars.count == 1,
                let first = lowerBound.first, let last = upperBound.first else { return nil }
        return (first...last).scalars
    }
    var all: [Bound]? { return scalars?.map(String.init) }
}

// MAKR: - Array extensions

extension Array where Element == Character {
    init?(_ range: ClosedRange<Element>) {
        guard let array = range.all else { return nil }
        self = array
    }
}

extension Array where Element == String {
    init?(_ range: ClosedRange<Element>) {
        guard let array = range.all else { return nil }
        self = array
    }
}

extension Array where Element == Unicode.Scalar { init(_ range: ClosedRange<Element>) { self = range.scalars } }
func test(value: Any) { print("-- \(type(of: value)) : \(value)") }

print("====================")
test(value: ("a"..."z").scalars ?? [])
test(value: ("a"..."z").all ?? [])
test(value: ("aa"..."z").all ?? [])
test(value: ("a"..."zz").all ?? [])
print("====================")
test(value: (Character("a")...Character("z")).scalars ?? [])
test(value: (Character("a")...Character("z")).all ?? [])
print("====================")
test(value: (Unicode.Scalar("a")...Unicode.Scalar("z")).scalars)
print("====================")
test(value: [Unicode.Scalar]("a"..."z"))
test(value: [Character]("a"..."z") ?? [])
test(value: [String]("a"..."z") ?? [])
test(value: [String]("aa"..."z") ?? [])
test(value: [String]("a"..."zz") ?? [])

回答by Vasily Bodnarchuk

Details

细节

  • Xcode Version 10.3 (10G8), Swift 5
  • Xcode 版本 10.3 (10G8),Swift 5

Solution 1

方案一

====================
-- Array<Scalar> : ["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"]
-- Array<String> : ["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"]
-- Array<String> : []
-- Array<String> : []
====================
-- Array<Scalar> : ["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"]
-- Array<Character> : ["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"]
====================
-- Array<Scalar> : ["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"]
====================
-- Array<Scalar> : ["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"]
-- Array<Character> : ["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"]
-- Array<String> : ["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"]
-- Array<String> : []
-- Array<String> : []

Usage 1

用法 1

extension Unicode.Scalar: Strideable {
    public typealias Stride = Int
    public func distance(to other: Unicode.Scalar) -> Stride { return abs(Int(value) - Int(other.value)) }
    public func advanced(by n: Stride) -> Unicode.Scalar { return Unicode.Scalar(value + UInt32(n)) ?? self }
}

extension Character: Strideable {
    public typealias Stride = Int
    public func distance(to other: Character) -> Stride {
        guard unicodeScalars.count == 1, other.unicodeScalars.count == 1 else { return 0 }
        return unicodeScalars.first!.distance(to: other.unicodeScalars.first!)
    }
    public func advanced(by n: Stride) -> Character {
        guard unicodeScalars.count == 1 else { return self }
        return Character(unicodeScalars.first!.advanced(by: n))
    }
}

extension Array where Element == String {
    init?(_ range: ClosedRange<Element>) {
        guard   range.lowerBound.unicodeScalars.count == 1, range.upperBound.unicodeScalars.count == 1,
                let first = range.lowerBound.unicodeScalars.first, let last = range.upperBound.unicodeScalars.first else { return nil }
        self = [Unicode.Scalar](first...last).map(String.init)
    }
}

Usage 1 log

用法 1 日志

func test(value: Any) { print("-- \(type(of: value)) : \(value)") }

test(value: [Unicode.Scalar]("a"..."z"))
test(value: [Character]("a"..."z"))
test(value: [String]("a"..."z"))
test(value: Array("a"..."z"))
test(value: Array(Character("a")...Character("z")))
test(value: Array(Unicode.Scalar("a")...Unicode.Scalar("z")))


Solution 2

解决方案2

-- Array<Scalar> : ["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"]
-- Array<Character> : ["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"]
-- Optional<Array<String>> : Optional(["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"])
-- Optional<Array<String>> : Optional(["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"])
-- Array<Character> : ["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"]
-- Array<Scalar> : ["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"]

Usage 2

用法2

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

Usage 2 log

使用 2 日志

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

回答by Mark

Solving for:

解决:

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"]

with Swift 4.2 / 5.0:

使用 Swift 4.2 / 5.0:

##代码##

yields:

产量:

##代码##

回答by ???

(11...36).map { String($0 - 1, radix: $0) }

(11...36).map { String($0 - 1, radix: $0) }

回答by coolly

You can simply use let alphabets: [UnicodeScalar] = Array("A"..."Z")

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