variable valor recorrer que obtener numerico enumerador enum asignar arrays swift enums

arrays - valor - que es enum



Obtenga todos los valores de enumeraciĆ³n como una matriz (12)

Para Swift 4.2 (Xcode 10) y posterior

Hay un protocolo 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) }

Para Swift <4.2

No, no puede consultar una enum para saber qué valores contiene. Ver este artículo Debe definir una matriz que enumere todos los valores que tiene. Consulte también la solución inteligente de 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) }

Tengo la siguiente enumeración.

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

Necesito obtener todos los valores en bruto como una matriz de cadenas (como ["Pending", "On Hold", "Done"] ).

Agregué este método a la enumeración.

func toArray() -> [String] { var n = 1 return Array( GeneratorOf<EstimateItemStatus> { return EstimateItemStatus(id: n++)!.description } ) }

Pero obtengo el siguiente error.

No se puede encontrar un inicializador para el tipo ''GeneratorOf'' que acepte una lista de argumentos del tipo ''(() -> _)''

No puedo entender cómo resolver esto. ¿Alguna ayuda? O dígame si hay una manera más fácil / mejor / más elegante de hacer esto.

Gracias.


Agregue el protocolo CaseIterable a la enumeración:

enum EstimateItemStatus: String, CaseIterable { case pending = "Pending" case onHold = "OnHold" case done = "Done" }

Uso:

let values: [String] = EstimateItemStatus.allCases.map { $0.rawValue } //["Pending", "OnHold", "Done"]


Después de la inspiración de Sequence y horas de prueba y errores. Finalmente obtuve este cómodo y hermoso Swift 4 way en 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 } }

Uso:

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

Salida:

Pending On Hold Done


Encontré en alguna parte este código:

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

Utilizar:

enum YourEnum: EnumCollection { //code } YourEnum.cases()

devolver la lista de casos de YourEnum


Hay otra forma que al menos es segura en tiempo de compilación:

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

Tenga en cuenta que esto funciona para cualquier tipo de enumeración (RawRepresentable o no) y también si agrega un nuevo caso, obtendrá un error del compilador que es bueno, ya que lo obligará a tener esto actualizado.


Para Swift 2

// Found http://.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)) }

Para usarlo:

arrayEnum(MyEnumClass.self)


Para obtener una lista con fines funcionales, use la expresión EnumName.allCases que devuelve una matriz, por ejemplo

EnumName.allCases.map{$0.rawValue}

le dará una lista de cadenas dado que EnumName: String, CaseIterable

Nota: use allCases lugar de AllCases() .


Puedes usar

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


Si su enumeración es incremental y está asociada con números, puede usar el rango de números que asigna a valores de enumeración, de esta manera:

// Swift 3 enum EstimateItemStatus: Int { case pending = 1, onHold done } let estimateItemStatusValues: [EstimateItemStatus?] = (EstimateItemStatus.pending.rawValue...EstimateItemStatus.done.rawValue).map { EstimateItemStatus(rawValue: $0) }

Esto no funciona con enumeraciones asociadas con cadenas o cualquier otra cosa que no sean números, ¡pero funciona muy bien si ese es el caso!


Actualización para Swift 5

La solución más fácil que he encontrado es usar .allCases en una enumeración que extiende 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 en cualquier enumeración CaseIterable devolverá una Collection de ese elemento.

var myEnumArray = EstimateItemStatus.allCases

más información sobre CaseIterable


Swift 4.2 presenta un nuevo protocolo llamado CaseIterable

enum Fruit : CaseIterable { case apple , apricot , orange, lemon }

que cuando se ajusta a, puede obtener una matriz de los casos de enum como este

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

["Pendiente", "En espera", "Listo"]