모든 열거값을 배열로 가져오는 방법
나는 다음과 같은 열거를 가지고 있다.
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(X코드 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)
}
스위프트 5
열거에 CaseItable 프로토콜 추가:
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
}
사용방법:
let values: [String] = EstimateItemStatus.allCases.map { $0.rawValue }
//["Pending", "OnHold", "Done"]
Swift 4.2는 다음과 같은 새로운 프로토콜을 도입합니다.CaseIterable
enum Fruit : CaseIterable {
case apple , apricot , orange, lemon
}
에 준거했을 경우, 에서 어레이를 취득할 수 있습니다.enum
이런 경우
for fruit in Fruit.allCases {
print("I like eating \(fruit).")
}
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
static var statusList: [String] {
return EstimateItemStatus.allCases.map { $0.rawValue }
}
}
['보류 중', '보류 중', '완료']
컴파일 시 최소한 안전한 다른 방법이 있습니다.
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
}
}
이것은 임의의 열거형(RawRepresentable 또는 Not)에 대해 동작합니다.또한 새로운 대소문자를 추가하면 컴파일러 에러가 발생합니다.그래서 이 에러가 최신이 되도록 강제합니다.
기능을 위해 목록을 가져오려면 다음 식을 사용합니다.EnumName.allCases
예를 들어 어레이를 반환합니다.
EnumName.allCases.map{$0.rawValue}
스트링 리스트가 표시됩니다.EnumName: String, CaseIterable
주의: 사용allCases
대신AllCases()
.
어디선가 이 코드를 찾았어요
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에서 케이스 목록 반환
Swift 5 업데이트
제가 찾은 가장 쉬운 해결책은.allCases
확장되어 있는 열거형으로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
어느 쪽이든CaseIterable
enum은 다음 값을 반환합니다.Collection
그 요소의.
var myEnumArray = EstimateItemStatus.allCases
CaseItable 상세
사용할 수 있다
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)
}
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)
Sequence에서 영감을 받은 후 몇 시간 동안 시행 오류가 발생했습니다.드디어 Xcode 9.1에서 편안하고 아름다운 Swift 4를 얻었습니다.
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
}
}
사용방법:
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)
}
출력:
Pending
On Hold
Done
열거형이 증분형이고 숫자와 연관된 경우 다음과 같이 열거형 값에 매핑하는 숫자 범위를 사용할 수 있습니다.
// Swift 3
enum EstimateItemStatus: Int {
case pending = 1,
onHold
done
}
let estimateItemStatusValues: [EstimateItemStatus?] = (EstimateItemStatus.pending.rawValue...EstimateItemStatus.done.rawValue).map { EstimateItemStatus(rawValue: $0) }
이것은 문자열이나 숫자 이외의 에넘에서는 잘 동작하지 않지만, 만약 그렇다면 매우 효과적입니다!
allValues를 생성할 열거형 확장입니다.
extension RawRepresentable where Self: CaseIterable {
static var allValues: [Self.RawValue] {
return self.allCases.map { $0.rawValue}
}
}
언급URL : https://stackoverflow.com/questions/32952248/how-to-get-all-enum-values-as-an-array
'programing' 카테고리의 다른 글
Swift3에서 fileprivate와 private를 구별하는 좋은 예는 무엇입니까? (0) | 2023.04.09 |
---|---|
대용량 엑셀 파일을 효율적으로 여는 방법 (0) | 2023.04.09 |
UITableView에서 자동 레이아웃을 사용하여 동적 셀 레이아웃 및 가변 열 높이 설정 (0) | 2023.04.09 |
@testable 사용 시 '모듈이 테스트용으로 컴파일되지 않았습니다' (0) | 2023.04.09 |
텍스트 선택 강조 표시를 비활성화하는 방법 (0) | 2023.04.09 |