Details
- Xcode Version 10.3 (10G8), Swift 5
Solution 1
// 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 } }
Usage 1
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") ?? [])
Usage 1 log
====================
-- 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> : []
Solution 2
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 2
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")))
Usage 2 log
-- 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"]