user3628240
user3628240

Reputation: 927

How to use switch with enum for string

Sorry for the extremely basic question, but I want to figure out how to use a switch statement with cases that check if it's a certain string.

For example if I have an AnimalType enum and then I have an animal struct:

enum AnimalType: String {
   case Mammal = "Mammal"
   case Reptile = "Reptile"
   case Fish = "Fish"
}

struct Animal {
   let name: String
   let type: String
}

If I want to go through a list of Animals and then have a switch statement, how would I match the Animal.Type string to the enum? I don't want to change the Animal struct to let type: AnimalType either.

switch Animal.type {
case :
...// how do I match the string to the enum?

Upvotes: 9

Views: 6633

Answers (5)

tiw
tiw

Reputation: 565

Paste the code below in your Playground to see how it works.

You can basically create a list with animals in it, and reach the rawValue of an AnimalType to check when the switch on each animal in your list matches like this:

import UIKit

enum AnimalType: String {
    case mammal = "Mammal"
    case reptile = "Reptile"
    case fish = "Fish"
    case cat = "Cat"
    case bug = "Bug"
}

struct Animal {
    let name: String
    let type: String
}

// Create some animals list
let animals: [Animal] = [Animal(name: "Kiwi", type: "Cat"),
                         Animal(name: "Copy", type: "Cat"),
                         Animal(name: "Oebi", type: "Cat"),
                         Animal(name: "Zaza", type: "Bug")]
// For each animal in the list
for animal in animals {
    // Check if its type actually matches a type from your enum
    switch animal.type {
    case AnimalType.cat.rawValue:
        print("\(animal.name) is a \(AnimalType.cat.rawValue)")
    case AnimalType.bug.rawValue:
        print("\(animal.name) is a \(AnimalType.bug.rawValue)")
    default:
        "This is not a cat nor a bug"
    }
    
}

Unless you want type of your Animal struct to be of AnimalType. If so, you can do this:

import UIKit

enum AnimalType: String {
    case mammal = "Mammal"
    case reptile = "Reptile"
    case fish = "Fish"
    case cat = "Cat"
    case bug = "Bug"
}

struct Animal {
    let name: String
    let type: AnimalType
}

// Create some animals list
let animals: [Animal] = [Animal(name: "Kiwi", type: .cat),
                         Animal(name: "Copy", type: .cat),
                         Animal(name: "Oebi", type: .cat),
                         Animal(name: "Zaza", type: .bug)]
// For each animal in the list
for animal in animals {
    // Check if its type actually matches a type from your enum
    switch animal.type {
    case .cat:
        print("\(animal.name) is a \(AnimalType.cat.rawValue)")
    case .bug:
        print("\(animal.name) is a \(AnimalType.bug.rawValue)")
    default:
        "This is not a cat nor a bug"
    }

}

Upvotes: 1

Abdurrahman Mubeen Ali
Abdurrahman Mubeen Ali

Reputation: 1341

If the strings are exactly the same as the enum, you don't have to define it. Following is my working solution.

enum SegueIdentifier: String {
    case pushViewController1
    case pushViewController2
    case pushViewController3
}

switch SegueIdentifier(rawValue: segue.identifier ?? "") {
case .pushViewController1:
     if let viewController1 = segue.destination as? ViewController1 {
         viewController1.customProperty = customPropertyValue
     }
case .pushViewController2:
     if let viewController2 = segue.destination as? ViewController2 {
         viewController2.customProperty = customPropertyValue
     }
case .pushViewController3:
     if let viewController3 = segue.destination as? ViewController3 {
         viewController3.customProperty = customPropertyValue
     }
default:
    let message = "This case has not been handled."
    let alertController = UIAlertController(title: "Alert", message: message, preferredStyle: .alert)
    let okayAction = UIAlertAction(title: "Okay", style: .default) { (_:UIAlertAction) in }

    alertController.addAction(okayAction)

    present(alertController, animated: true, completion: nil)
}

Upvotes: 0

badhanganesh
badhanganesh

Reputation: 3465

I'd suggest you to use enum for comparison and making it optional for the type. You could also use rawValue of the enum to compare them.

enum AnimalType: String { 
    case Mammal //No need of case Mammal = "Mammal"
    case Reptile
    case Fish
}

struct Animal {
    let name: String
    let type: AnimalType?
}


let lion = Animal(name: "Lion", type: .Mammal)

switch lion.type {

case .Mammal?:
    break
case .Reptile?:
    break
case .Fish?:
    break
case nil:
    break

}


EDIT:
As Matthew in the comment said, if you’re getting the objects from a server, you need to have custom decoding process to convert the string response to corresponding AnimalType enum for comparison. Otherwise you’re good with using just the enum.

Upvotes: 1

Glaphi
Glaphi

Reputation: 452

You can create an animal type from string rawValue and switch on that: But first I'd change the cases to lowercase, thats the preferred style in Swift.

func checkType(of animal: Animal) {
    guard let animalType = AnimalType(rawValue: animal.type) else {
        print("Not an animal type")
        return
    }
    switch animalType {
    case .mammal: break
    case .reptile: break
    case .fish: break
    }
}

Alternatively, you can also switch on the string and compare if it matches any of your AnimalType rawValues:

func checkType(of animal: Animal) {
    switch animal.type {
    case AnimalType.mammal.rawValue: break
    case AnimalType.reptile.rawValue: break
    case AnimalType.fish.rawValue: break
    default:
        print("Not an animal type")
        break
    }
}

Upvotes: 7

Ferrakkem Bhuiyan
Ferrakkem Bhuiyan

Reputation: 2783

enum Command: String {
   case Mammal = "Mammal"
   case Reptile = "Reptile"
   case Fish = "Fish"
}

let command = Command(rawValue: "d")

switch command {
case .Mammal?:
    print("Mammal")
case .Reptile?:
    print("second")
case .Fish?:
    print("third")
case nil:
    print("not found")
}
// prints "not found"

Upvotes: 8

Related Questions