Daniel Klöck
Daniel Klöck

Reputation: 21137

find an enum type in an array

If I have this enum:

enum TestEnum {
    case typeA
    case typeB(Int)
}

and this array: let testArray = [TestEnum.typeB(1), .typeA, .typeB(3)]

Is there a less ugly way to find if an item is contained in that array than:

if testArray.contains(where: {if case .typeA = $0 { return true }; return false}) {
    print("contained")
} else {
    print("not found")
}

Upvotes: 2

Views: 72

Answers (3)

Fogmeister
Fogmeister

Reputation: 77621

If you make your enum equatable you could do something like this...

enum TestEnum: Equatable {
    case testA
    case testB(Int)

    static func ==(lhs: TestEnum, rhs: TestEnum) -> Bool {
        switch (lhs, rhs) {
        case (.testA, .testA):
            return true
        case (.testB(let a), .testB(let b)):
            return a == b
        default:
            return false
        }
    }
}

let array: [TestEnum] = [.testA, .testB(1)]

array.contains(.testA) // true
array.contains(.testB(1)) // true
array.contains(.testB(3)) // false

This means you can use the simpler form of the contains function and not have to use the block at all.

Upvotes: 2

Bruno
Bruno

Reputation: 212

To make this more readable you could add a function to your enum like this:

enum TestEnum {
    case typeA
    case typeB(Int)

    static func ==(a: TestEnum, b: TestEnum) -> Bool {
        switch (a, b) {
        case (typeB(let a), .typeB(let b)) where a == b: return true
        case (.typeA, .typeA): return true
        default: return false
        }
    }
}

let testArray = [TestEnum.typeB(1), .typeA, .typeB(3)]

if testArray.contains(where: { $0 == .typeA }) {
    print("contained")
} else {
    print("not found")
}

Upvotes: 2

jefflovejapan
jefflovejapan

Reputation: 2121

Not really, but you could define a helper on your enum to make it a little less gross at the call site.

enum TestEnum {
  case typeA
  case typeB(Int)

  var isTypeA: Bool {
    switch self {
      case .typeA:
      return true
      case .typeB:
      return false
    }
  }
}

let filtered: [TestEnum] = [.typeB(1), .typeA, .typeB(3)].filter { $0.isTypeA }

Upvotes: 1

Related Questions