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
Swift: generate an array of (Swift) characters
提问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"]
*/
- Create a range of Unicode scalars that match the code points for uppercased latin alphabet Unicode block.
- 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
'svalue
property
. - Iterate over your range of Unicode scalar numeric representations in order to create an array of Unicode scalars.
- Iterate over your array of Unicode scalars in order to create an array of characters.
- 创建一系列与大写拉丁字母 Unicode 块的代码点匹配的 Unicode 标量。
- 因为第一个范围是不可跨越的(您不能对其进行迭代),所以使用
Unicode.Scalar
's将其转换为一系列 Unicode 标量数字表示。value
property
- 迭代您的 Unicode 标量数字表示范围,以创建 Unicode 标量数组。
- 迭代您的 Unicode 标量数组以创建字符数组。
As an alternative, you can use one of the sample codes below if you need to start from a range of Character
s or a range of String
s:
作为替代方案,如果您需要从Character
s 范围或 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")