How to Define an Array of a Particular Enum Case in Swift

how to define an array of a particular enum case in swift

All cases of an enum are of the same enum type, so you cannot declare an Array that can only hold a specific case of an enum.

However, you can achieve your goals by creating 2 enums instead of one and making the Menu.submenu enum case take the other enum as its associated value.

enum Menu {
case item(MenuItem)
case submenu([MenuItem])
}

enum MenuItem {
case item(String)
}

Then you can use it like

let menu = Menu.item(.item("main"))
let submenu = Menu.submenu([.item("a"), .item("b")])

How to get all enum values as an array

For Swift 4.2 (Xcode 10) and later

There's a CaseIterable protocol:

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

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

how to use an array as a case of an enum

Just create a static property:



enum Types: String, Codable, CaseIterable {
case type1, type2, type3, type4, type5
static let someCases: [Types] = [.type1, .type2, .type3]
}


Types.someCases  // [type1, type2, type3]

Swift array holding any enum String type

Just think about it logically: You want to store multiple enums in an array, so it can be either this or that enum, which is just what an enum is! You can declare an new enum that has associated values of all the accepted other enums like so:

enum A {
case A1, A2
}

enum B {
case B1, B2
}

enum All {
case First(A)
case Second(B)
}

Then you can create an array like this:

let array : [All] = [
.First(.A1),
.Second(.B2),
.Second(.B1),
.First(.A1)
]

Swift - find object in array of enums with associated values

You can use pattern matching to accomplish this with 2 ways.

Using switch:

let cat = animals.first(where: {
switch $0 {
case .cat(let catModel) where catModel.litterBoxId == 7:
return true
default:
return false
}
})

or if:

let cat = animals.first(where: {
if case .cat(let catModel) = $0, catModel.litterBoxId == 7 {
return true
}
return false
})

Update: As @Alexander-ReinstateMonica mentioned in his commnet, it would be more appropriate to hide this logic behind a function like this:

extension Animal {
func matches(litterboxID: Int) -> Bool {
switch self {
case .cat(let catModel) where catModel.litterBoxId == 7:
return true
default:
return false
}
}
}

and then your code will be much cleaner:

let cat = animals.first(where: { $0.matches(litterboxID: 7) })

How can I create an array of enum values from an array of Strings

You could achieve it by mapping the current array of strings to an array of enum cases based on their rawValues:

let array = ["music", "cars", "tomato"]
let arrayEnum = array.map { Products(rawValue: $0) }

At this point, keep in mind that arrayEnum is [Products?] containing 3 elements because mapping "tomato" string gives nil. What you could do for getting rid of nils is to use the compactMap:

let array = ["music", "cars", "tomato"]

let arrayEnum = array.compactMap { Products(rawValue: $0) }
print(arrayEnum)

Now arrayEnum contains only two elements without the nil one.

Switch statement with array of enum cases

You first need to loop over the array and then you can use the switch

func foo () {
for direction in directions {
switch direction {
case .north: print("Going north")
case .west: print("Going west")
case .east: print("Going east")
case .south: print("Going south")
}
}
}

The name of the enum should be singular so Direction instead of Directions



Related Topics



Leave a reply



Submit