我有以下枚举。
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
}
)
}
但是我收到了以下错误。
找不到类型&#39; GeneratorOf&#39;的初始化程序。接受类型&#39;(() - &gt; _)&#39;
的参数列表我无法弄清楚如何解决这个问题。有帮助吗?或者请告诉我是否有更容易/更好/更优雅的方式来做到这一点。
谢谢。
答案 0 :(得分:84)
有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)
}
不,您无法向enum
查询其包含的值。见this article。您必须定义一个列出所有值的数组。还可以查看Frank Valbuena的clever solution。
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)
}
答案 1 :(得分:22)
Swift 4.2 引入了一个名为CaseIterable
enum Fruit : CaseIterable {
case apple , apricot , orange, lemon
}
当你符合时,你可以从像这样的enum
案例中获得一个数组
for fruit in Fruit.allCases {
print("I like eating \(fruit).")
}
答案 2 :(得分:14)
还有另一种方法,至少在编译时是安全的:
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与否)以及如果添加新案例,那么您将收到一个好的编译器错误,因为这会强制您使其保持最新状态。
答案 3 :(得分:12)
我找到了这个代码:
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返回案例列表
答案 4 :(得分:6)
将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"]
答案 5 :(得分:1)
对于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)
答案 6 :(得分:1)
来自Sequence的灵感和几小时的尝试n错误。我终于在Xcode 9.1上获得了这个舒适漂亮的Swift 4方式:
directed-link-breed [Ls L]
to star
ca
nw:generate-star turtles Ls 100 ; using link breed
[
set color red
fd random 15
set shape "circle"
ask links [set color yellow]
]
nw:generate-star turtles Ls-to 100 ; it does not work
end
用法:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="557.0" prefWidth="1012.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<SplitPane fx:id="splitPane" dividerPositions="0.5" layoutX="-8.0" layoutY="35.0" mouseTransparent="true" prefHeight="529.0" prefWidth="1027.0" style="-fx-background-color: #EEEEEE;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="28.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list_todo" layoutY="-8.0" prefHeight="527.0" prefWidth="584.0" style="-fx-padding: 3px;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list_done" layoutY="14.0" prefHeight="527.0" prefWidth="420.0" style="-fx-padding: 3px;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children></AnchorPane>
</items>
</SplitPane>
<MenuBar prefHeight="30.0" prefWidth="1012.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<menus>
<Menu fx:id="menu_cambiarUser" mnemonicParsing="false" text="Cambiar usuario" />
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
</children>
</AnchorPane>
输出:
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
}
}
答案 7 :(得分:1)
您可以使用
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)
}
答案 8 :(得分:1)
要获取出于功能目的的列表,请使用表达式EnumName.allCases
,该表达式返回一个数组,例如
EnumName.allCases.map{$0.rawValue}
鉴于EnumName: String, CaseIterable
,将为您提供字符串列表
注意:使用allCases
代替AllCases()
。
答案 9 :(得分:0)
如果您的枚举是增量的并且与数字相关联,则可以使用映射到枚举值的数字范围,如下所示:
// Swift 3
enum EstimateItemStatus: Int {
case pending = 1,
onHold
done
}
let estimateItemStatusValues: [EstimateItemStatus?] = (EstimateItemStatus.pending.rawValue...EstimateItemStatus.done.rawValue).map { EstimateItemStatus(rawValue: $0) }
对于与字符串或数字以外的任何其他内容相关的枚举,这并不适用,但如果是这样的话,效果会非常好!
答案 10 :(得分:0)
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
将返回该元素的Collection
。
var myEnumArray = EstimateItemStatus.allCases
的更多信息
答案 11 :(得分:0)
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
static var statusList: [String] {
return EstimateItemStatus.allCases.map { $0.rawValue }
}
}
[“待处理”,“暂停”,“完成”]
答案 12 :(得分:0)
扩展枚举以创建allValues。
extension RawRepresentable where Self: CaseIterable {
static var allValues: [Self.RawValue] {
return self.allCases.map { $0.rawValue}
}
}