Multiple Enum Types List All Cases

Multiple enum types list all cases

Here is a demo of possible solution. Prepared with Xcode 12.1 / iOS 14.1

demo

enum Fish: String, CaseIterable {
case goldfish
case blueTang = "blue_tang"
case shark
}

func view<T: CaseIterable & Hashable>(for type: T.Type) -> some View where T.AllCases: RandomAccessCollection {
VStack(alignment: .leading) {
Text(String(describing: type)).bold()
ForEach(type.allCases, id: \.self) { item in
Text(String(describing: item))
}
}
}

struct FishDemoView: View {
var body: some View {
view(for: Fish.self)
}
}

Is it possible group & represent multiple cases as another case within an enum in Swift?

You can used nested Enum and a case with parameter

enum Devices {
case phone(iPhone)
case tablet(iPad)

enum iPhone {
case phone7
case phoneX
}

enum iPad {
case mini
case pro
}
}

let randomDevice = Devices.phone(.phone7)

switch randomDevice {
case .phone:
print("Its a phone")
default:
break
}

// prints "Its a phone"

How do you pass multiple enum values in C#?

When you define the enum, just attribute it with [Flags], set values to powers of two, and it will work this way.

Nothing else changes, other than passing multiple values into a function.

For example:

[Flags]
enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}

public void RunOnDays(DaysOfWeek days)
{
bool isTuesdaySet = (days & DaysOfWeek.Tuesday) == DaysOfWeek.Tuesday;

if (isTuesdaySet)
//...
// Do your work here..
}

public void CallMethodWithTuesdayAndThursday()
{
this.RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
}

For more details, see MSDN's documentation on Enumeration Types.


Edit in response to additions to question.

You won't be able to use that enum as is, unless you wanted to do something like pass it as an array/collection/params array. That would let you pass multiple values. The flags syntax requires the Enum to be specified as flags (or to bastardize the language in a way that's its not designed).

Multiple Enums with same case

You could create one state enum that uses generics:

enum ViewModelState<T> {
case failure(String)
case anotherState(T)
}

Check enum for multiple values

I ended up writing a method:

public static enum FileType {
CSV, XML, XLS, TXT, FIXED_LENGTH;

// Java < 8
public boolean in(FileType... fileTypes) {
for(FileType fileType : fileTypes) {
if(this == fileType) {
return true;
}
}

return false;
}

// Java 8
public boolean in(FileType... fileTypes) {
return Arrays.stream(fileTypes).anyMatch(fileType -> fileType == this);
}
}

And then:

if(fileType.in(FileType.CSV, FileType.TXT, FileType.FIXED_LENGTH)) {}

Nice and clean!

How could I use the multiple Enum raw values of type Int in Swift?

Enum cases can not have multiple rawValues. Becase imagine you call this:

print( STATUS_CODE.onGoing.rawValue )

What value you expect to be printed?


Instead you can have a custom enum like the one you think of:

enum STATUS_CODE: RawRepresentable {

init(rawValue: Int) {
switch rawValue {
case 5, 50,70, 90: self = .onGoing(rawValue)
case 10: self = .atWorkshop
case 16: self = .completed
case 35: self = .comedy
case 80: self = .crime
case 0: self = .NoDate

default: self = .unknown(rawValue)
}
}

var rawValue: Int {
switch self {
case .onGoing(let rawValue): return rawValue
case .atWorkshop: return 10
case .completed: return 16
case .comedy: return 35
case .crime: return 80
case .NoDate: return 0
case .unknown(let rawValue): return rawValue
}
}

case onGoing(Int)
case atWorkshop
case completed
case comedy
case crime
case NoDate

case unknown(Int)

func getString() -> String {
switch self {
case .onGoing : return "New order"
case .atWorkshop: return "At workshop"
case .completed : return "Animation"
case .comedy : return "Comedy"
case .crime : return "Crime"
case .NoDate : return "No Order"

case .unknown(let rawValue): return "Unknown \(rawValue)"
}
}
}

ofcourse it is a demo and can be refactored ;)

Create a DRY function for multiple enums (enum subclassing?)

A protocol is the right approach. Not sure why do you think protocols cannot inherit from each other, but they can, so you can make your protocol inherit from CaseIterable.

You can also significantly simplify titled by using map instead of a for..in loop and getting rid of the useless get specifier. A getter is the default accessor for a computed property, you don't need to wrap your closure in get { ... } unless you are creating both a getter and a setter.

protocol Titled: CaseIterable {
var title: String { get }
static var titles: [String] { get }
}

extension Titled {
static var titles: [String] { allCases.map(\.title) }
}

Then you just need to keep the title property on your enums and make them conform to Titled and due to the default implementation you get titles for free.

Unrelated to your question, but enum cases should be lowerCamelCase like all variables.

enum CustomerTypes: Int, Titled {
case newCustomer = 0
case existingCustomer
case myself

var title: String {
switch self {
case .newCustomer : return "new"
case .existingCustomer : return "existing"
case .myself : return "my"
}
}
}

enum EnquiryTypes: Int, Titled {
case phone = 0
case faceToFace

var title: String {
switch self {
case .phone : return "phone"
case .faceToFace : return "face"
}
}
}

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

Java enum with multiple value types

First, the enum methods shouldn't be in all caps. They are methods just like other methods, with the same naming convention.

Second, what you are doing is not the best possible way to set up your enum. Instead of using an array of values for the values, you should use separate variables for each value. You can then implement the constructor like you would any other class.

Here's how you should do it with all the suggestions above:

public enum States {
...
MASSACHUSETTS("Massachusetts", "MA", true),
MICHIGAN ("Michigan", "MI", false),
...; // all 50 of those

private final String full;
private final String abbr;
private final boolean originalColony;

private States(String full, String abbr, boolean originalColony) {
this.full = full;
this.abbr = abbr;
this.originalColony = originalColony;
}

public String getFullName() {
return full;
}

public String getAbbreviatedName() {
return abbr;
}

public boolean isOriginalColony(){
return originalColony;
}
}


Related Topics



Leave a reply



Submit