0

Let's say I have a public enum, each of which has multiple associated values. I currently have them stored as such:

public enum foo {
    case A
    case B
    case C
    case ... //goes on for hundreds of enums
}

To access a value, I do a linear search using a switch statement as such (within the enum):

func getNumber() -> Int { //multiple functions just like this for each A, B, C...
    switch self {
    case .A: return 102  //numbers are arbitrary
    case .B: return 438
    case .C: return 293
    case ... //and so on
    }
}

func getName() -> String {
    switch self {
    case .A: return "Apple" //names are arbitrary as well...
    case .B: return "Banana"
    case .C: return "Cherry"
    case ...
    }
}

func ...

However, to access something at the bottom of the list, I have to iterate through every single value of the enum, which has to be done multiple times a second. I feel as if this is very inefficient. Ideally, I'd like to be able to:

  • Store multiple elements, each with their own individual values. Each element should have multiple similar variables (name, weight, size, etc.) associated with it, just with different values for each.

  • Be able to access each enum without having to iterate through a switch statement. For example, if a user inputs foo.B.number(), ideally it would return "438" without having to go through each element.

  • NOT subject to change (B's "number" will never be modified, etc.). These values are FINAL.

  • Be able to access a certain enum with a String. For example, if "Apple" is associated with foo's "A", then a function as such can be called:

    func getFoo(s:String) -> foo { ... }

    getFoo(s:"Apple") //should return A

What could I do to store and access these?

Matt
  • 17
  • 3
  • 2
    It is Swift naming convention to name your enumerations starting with an uppercase letter and its cases with lowercase. – Leo Dabus Mar 22 '18 at 15:47
  • What makes you think that switching does a linear search? If there are sufficiently many cases to warrant it, the compiler builds a (hash keyed) lookup table. Though for most use cases (enums without many enum cases), linear search is actually the fastest approach. – Alexander Mar 22 '18 at 16:01

1 Answers1

1

The most efficient way to do this in swift is to use a dictionary and tuple (tuples group data together, dictionaries are a great way to store lots of data and find it efficiently)

public enum Foo {
 case A, B, C, D, E, F //and on
}

let dictionary: [Foo: (number: Int, name: String)] = [
.A: (102,"Apple")
]

// then call the values

let favoriteFruitOfA = dictionary[.A].name

however you might want to ditch the enum if you have hundreds of values. enums are great for declaring exhaustive list of discrete values e.g. north, south, east , west. Furthermore, enum declares a type which is why it's capitalized, which makes me think you're trying to use the enum to declare a property and shouldn't be using it. cheers.

Aaron Halvorsen
  • 2,610
  • 1
  • 23
  • 31
  • I think this is the way to go! Quick question, how would I be able to get A if I were to only be provided the string "Apple"? – Matt Mar 22 '18 at 16:02
  • Enums with hundreds of values still have a place in some use cases. They still guarantee exhaustiveness in switch cases, and they act like stored constants. You'll be surprised how many instances of "USA" we had in one of our DBs, just because the countries (and their names) an enum. USA, US, America, United States, Unites States of America... – Alexander Mar 22 '18 at 16:03
  • @Matt You would need to make a bimap https://stackoverflow.com/a/47081889/3141234 – Alexander Mar 22 '18 at 16:04
  • @Matt You could simply create one like: `var fruitToFooMapping = { Dictionary(uniqueKeysWithValues: dictionary.lazy.map { keyValuePair in (keyValuePair.value.name, keyValuePair.key) }) }()` – Alexander Mar 22 '18 at 16:09
  • Alexander is right. Also, if you're having trouble navigating some of this closure syntax this might get you headed in the right direction: https://stackoverflow.com/questions/27218669/swift-dictionary-get-key-for-value – Aaron Halvorsen Mar 22 '18 at 17:21