모든 열거 형 값을 배열로 가져옵니다.
다음 열거 형이 있습니다.
enum EstimateItemStatus: Printable {
case Pending
case OnHold
case Done
var description: String {
switch self {
case .Pending: return "Pending"
case .OnHold: return "On Hold"
case .Done: return "Done"
}
}
init?(id : Int) {
switch id {
case 1:
self = .Pending
case 2:
self = .OnHold
case 3:
self = .Done
default:
return nil
}
}
}
모든 원시 값을 문자열 배열로 가져와야 ["Pending", "On Hold", "Done"]합니다.
이 메서드를 열거 형에 추가했습니다.
func toArray() -> [String] {
var n = 1
return Array(
GeneratorOf<EstimateItemStatus> {
return EstimateItemStatus(id: n++)!.description
}
)
}
하지만 다음과 같은 오류가 발생합니다.
'(()-> _)'유형의 인수 목록을 허용하는 'GeneratorOf'유형에 대한 이니셜 라이저를 찾을 수 없습니다.
이 문제를 해결하는 방법을 알 수 없습니다. 도움이 필요하세요? 또는이 작업을 수행하는 더 쉽고 / 더 나은 / 더 우아한 방법이 있는지 알려주세요.
감사합니다.
Swift 4.2 (Xcode 10) 이상
있다 CaseIterable프로토콜 :
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
init?(id : Int) {
switch id {
case 1: self = .pending
case 2: self = .onHold
case 3: self = .done
default: return nil
}
}
}
for value in EstimateItemStatus.allCases {
print(value)
}
Swift <4.2의 경우
아니요, enum어떤 값이 포함되어 있는지를 쿼리 할 수 없습니다 . 이 기사를 참조 하십시오 . 가지고있는 모든 값을 나열하는 배열을 정의해야합니다. 또한 Frank Valbuena의 영리한 솔루션을 확인하십시오 .
enum EstimateItemStatus: String {
case Pending = "Pending"
case OnHold = "OnHold"
case Done = "Done"
static let allValues = [Pending, OnHold, Done]
init?(id : Int) {
switch id {
case 1:
self = .Pending
case 2:
self = .OnHold
case 3:
self = .Done
default:
return nil
}
}
}
for value in EstimateItemStatus.allValues {
print(value)
}
Swift 4.2 는CaseIterable
enum Fruit : CaseIterable {
case apple , apricot , orange, lemon
}
을 준수하면 다음 enum과 같은 경우 에서 배열을 얻을 수 있습니다.
for fruit in Fruit.allCases {
print("I like eating \(fruit).")
}
적어도 컴파일 타임에 안전한 또 다른 방법이 있습니다.
enum MyEnum {
case case1
case case2
case case3
}
extension MyEnum {
static var allValues: [MyEnum] {
var allValues: [MyEnum] = []
switch (MyEnum.case1) {
case .case1: allValues.append(.case1); fallthrough
case .case2: allValues.append(.case2); fallthrough
case .case3: allValues.append(.case3)
}
return allValues
}
}
이것은 모든 enum 유형 (RawRepresentable 여부)에 대해 작동하고 새 케이스를 추가하면 컴파일러 오류가 발생하여 최신 상태로 유지해야합니다.
어딘가에서이 코드를 찾았습니다.
protocol EnumCollection : Hashable {}
extension EnumCollection {
static func cases() -> AnySequence<Self> {
typealias S = Self
return AnySequence { () -> AnyIterator<S> in
var raw = 0
return AnyIterator {
let current : Self = withUnsafePointer(to: &raw) { $0.withMemoryRebound(to: S.self, capacity: 1) { $0.pointee }
}
guard current.hashValue == raw else { return nil }
raw += 1
return current
}
}
}
}
사용하다:
enum YourEnum: EnumCollection { //code }
YourEnum.cases()
YourEnum에서 사례 목록 반환
열거 형에 CaseIterable 프로토콜을 추가 합니다.
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
}
용법:
let values: [String] = EstimateItemStatus.allCases.map { $0.rawValue }
//["Pending", "OnHold", "Done"]
기능적 목적으로 목록을 얻으려면 EnumName.allCases배열을 반환하는 표현식 을 사용하십시오.
EnumName.allCases.map{$0.rawValue}
주어진 문자열 목록을 제공합니다. EnumName: String, CaseIterable
참고 : allCases대신 AllCases().
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
static var statusList: [String] {
return EstimateItemStatus.allCases.map { $0.rawValue }
}
}
[ "보류", "보류", "완료"]
Swift 2의 경우
// Found http://stackoverflow.com/questions/24007461/how-to-enumerate-an-enum-with-string-type
func iterateEnum<T where T: Hashable, T: RawRepresentable>(_: T.Type) -> AnyGenerator<T> {
var i = 0
return AnyGenerator {
let next = withUnsafePointer(&i) {
UnsafePointer<T>($0).memory
}
if next.hashValue == i {
i += 1
return next
} else {
return nil
}
}
}
func arrayEnum<T where T: Hashable, T: RawRepresentable>(type: T.Type) -> [T]{
return Array(iterateEnum(type))
}
그것을 사용하려면 :
arrayEnum(MyEnumClass.self)
After inspiration from Sequence and hours of try n errors. I finally got this comfortable and beautiful Swift 4 way on Xcode 9.1:
protocol EnumSequenceElement: Strideable {
var rawValue: Int { get }
init?(rawValue: Int)
}
extension EnumSequenceElement {
func distance(to other: Self) -> Int {
return other.rawValue - rawValue
}
func advanced(by n: Int) -> Self {
return Self(rawValue: n + rawValue) ?? self
}
}
struct EnumSequence<T: EnumSequenceElement>: Sequence, IteratorProtocol {
typealias Element = T
var current: Element? = T.init(rawValue: 0)
mutating func next() -> Element? {
defer {
if let current = current {
self.current = T.init(rawValue: current.rawValue + 1)
}
}
return current
}
}
Usage:
enum EstimateItemStatus: Int, EnumSequenceElement, CustomStringConvertible {
case Pending
case OnHold
case Done
var description: String {
switch self {
case .Pending:
return "Pending"
case .OnHold:
return "On Hold"
case .Done:
return "Done"
}
}
}
for status in EnumSequence<EstimateItemStatus>() {
print(status)
}
// Or by countable range iteration
for status: EstimateItemStatus in .Pending ... .Done {
print(status)
}
Output:
Pending
On Hold
Done
You Can Use
enum Status: Int{
case a
case b
case c
}
extension RawRepresentable where Self.RawValue == Int {
static var values: [Self] {
var values: [Self] = []
var index = 1
while let element = self.init(rawValue: index) {
values.append(element)
index += 1
}
return values
}
}
Status.values.forEach { (st) in
print(st)
}
If your enum is incremental and associated with numbers, you can use range of numbers that you map to enum values, like so:
// Swift 3
enum EstimateItemStatus: Int {
case pending = 1,
onHold
done
}
let estimateItemStatusValues: [EstimateItemStatus?] = (EstimateItemStatus.pending.rawValue...EstimateItemStatus.done.rawValue).map { EstimateItemStatus(rawValue: $0) }
This doesn't quite work with enums associated with strings or anything other than numbers, but it works great if that is the case!
Update for Swift 5
Easiest solution I've found is to use .allCases on an enum that extends CaseIterable
enum EstimateItemStatus: CaseIterable {
case Pending
case OnHold
case Done
var description: String {
switch self {
case .Pending: return "Pending"
case .OnHold: return "On Hold"
case .Done: return "Done"
}
}
init?(id : Int) {
switch id {
case 1:
self = .Pending
case 2:
self = .OnHold
case 3:
self = .Done
default:
return nil
}
}
}
.allCases on any CaseIterable enum will return a Collection of that element.
var myEnumArray = EstimateItemStatus.allCases
more info about CaseIterable
참고URL : https://stackoverflow.com/questions/32952248/get-all-enum-values-as-an-array
'Program Club' 카테고리의 다른 글
| div가 전체 높이를 확장하려면 (0) | 2020.11.19 |
|---|---|
| 내 npm 모듈은 Mac OS X에서 어디에 설치해야합니까? (0) | 2020.11.19 |
| Python에서 함수 호출의 실행 시간을 제한하는 방법 (0) | 2020.11.19 |
| 파일 이름의 배치 명령 날짜 및 시간 (0) | 2020.11.19 |
| Spring MVC의 뷰 기술로 JSF 사용 (0) | 2020.11.19 |