ios 如何将所有枚举值作为数组获取
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32952248/
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
How to get all enum values as an array
提问by Isuru
I have the following enum.
我有以下枚举。
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
}
}
}
I need to get all the raw values as an array of strings (like so ["Pending", "On Hold", "Done"]
).
我需要将所有原始值作为字符串数组获取(像这样["Pending", "On Hold", "Done"]
)。
I added this method to the enum.
我将此方法添加到枚举中。
func toArray() -> [String] {
var n = 1
return Array(
GeneratorOf<EstimateItemStatus> {
return EstimateItemStatus(id: n++)!.description
}
)
}
But I'm getting the following error.
但我收到以下错误。
Cannot find an initializer for type 'GeneratorOf' that accepts an argument list of type '(() -> _)'
无法找到接受类型为“(() -> _)”的参数列表的“GeneratorOf”类型的初始值设定项
Is there is an easier, better or more elegant way to do this?
有没有更简单、更好或更优雅的方法来做到这一点?
回答by Code Different
For Swift 4.2 (Xcode 10) and later
对于 Swift 4.2 (Xcode 10) 及更高版本
There's a CaseIterable
protocol:
有一个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)
}
For Swift < 4.2
对于 Swift < 4.2
No, you can't query an enum
for what values it contains. See this article. You have to define an array that list all the values you have. Also check out Frank Valbuena's solution in "How to get all enum values as an array".
不,您不能查询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)
}
回答by Sh_Khan
Swift 4.2introduces a new protocol named CaseIterable
Swift 4.2引入了一个名为的新协议CaseIterable
enum Fruit : CaseIterable {
case apple , apricot , orange, lemon
}
that when you conforms to , you can get an array from the enum
cases like this
当你符合时,你可以从这样的enum
情况中得到一个数组
for fruit in Fruit.allCases {
print("I like eating \(fruit).")
}
回答by maxwell
Add CaseIterableprotocol to enum:
将CaseIterable协议添加到枚举:
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
}
Usage:
用法:
let values: [String] = EstimateItemStatus.allCases.map { 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
}
}
.rawValue }
//["Pending", "OnHold", "Done"]
回答by Frank Valbuena
There's another way that at least is safe at compile time:
还有另一种方法至少在编译时是安全的:
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) { enum YourEnum: EnumCollection { //code }
YourEnum.cases()
.withMemoryRebound(to: S.self, capacity: 1) { EnumName.allCases.map{enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
static var statusList: [String] {
return EstimateItemStatus.allCases.map { 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
}
}
.rawValue }
}
}
.rawValue}
.pointee }
}
guard current.hashValue == raw else { return nil }
raw += 1
return current
}
}
}
}
Notice that this works for any enum type (RawRepresentable or not) and also if you add a new case then you will get a compiler error which is good since will force you to have this up to date.
请注意,这适用于任何枚举类型(RawRepresentable 与否),并且如果您添加一个新案例,那么您将收到一个编译器错误,这很好,因为这将迫使您将其更新。
回答by Daniel Kuta
I found somewhere this code:
我在某处找到了这个代码:
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)
}
Use:
用:
Pending
On Hold
Done
return list of cases from YourEnum
从 YourEnum 返回案例列表
回答by u2041954
To get a list for functional purposes, use the expression EnumName.allCases
which returns an array e.g.
要获取用于功能目的的列表,请使用EnumName.allCases
返回数组的表达式,例如
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)
}
will give you a list of Strings given that EnumName: String, CaseIterable
会给你一个字符串列表,因为 EnumName: String, CaseIterable
Note: use allCases
instead of AllCases()
.
注意:使用allCases
代替AllCases()
.
回答by Vladimir Pchelyakov
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
}
}
}
["Pending", "OnHold", "Done"]
[“待定”、“暂停”、“完成”]
回答by mclam
回答by Carlos Chaguendo
You Can Use
您可以使用
##代码##回答by Christopher Larsen
Update for Swift 5
Swift 5 更新
Easiest solution I've found is to use .allCases
on an enum that extends CaseIterable
我发现的最简单的解决方案是.allCases
在扩展的枚举上使用CaseIterable
.allCases
on any CaseIterable
enum will return a Collection
of that element.
.allCases
在任何CaseIterable
枚举上将返回Collection
该元素的一个。
more info about CaseIterable
有关CaseIterable 的更多信息