WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Question about Functions and Switch case

Forums > SwiftUI

Can it be possible to put a switch case inside a function that recieves a String and returns a Double? Would that even work?

   

Rodney posts a coding challenge!

Can it be possible to put a switch case inside a function that recieves a String and returns a Double?

Challenge accepted!

// Paste into Playgrounds
// This is a function that takes a string
// And returns a double.
func pseudoRandom(seed: String) -> Double {
    // Bogus logic implemented in a switch case.
    switch seed.count {
    case 0:
        return 0.0 
    case 1:
        return 7.999
    default:
        return 42.0  // the answer to the Ultimate Question of Life, the Universe, and Everything
    }
}

print("Winning Number: \(pseudoRandom(seed: "Obelix"))")

Do I win a prize ?

   

You can as @Obelix has shown and here

func stringToDouble(string: String) -> Double {
    switch string {
    case "one":
        return 1
    case "two":
        return 2
    case "three":
        return 3
    default:
        return 0
    }
}

print(stringToDouble(string: "one"))

This will print 1.0 as correct but however strings are case sensitive so if you had

print(stringToDouble(string: "One"))

or had any "spaces" in

print(stringToDouble(string: "  one   "))

then would print the default value of 0.0

So then you would have to add some extra code to fix this

func stringToDouble(string: String) -> Double {
    let newString = string.trimmingCharacters(in: .whitespacesAndNewlines)

    switch newString.lowercased() {
    case "one":
        return 1
    case "two":
        return 2
    case "three":
        return 3
    default:
        return 0
    }
}
print(stringToDouble(string: "One"))
print(stringToDouble(string: "one"))
print(stringToDouble(string: " one  "))

This will print 1.0 for all

1      

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Now can you do two strings and return a double...?

   

Rodney doubles down:

Now can you do two strings and return a double...?

Of course! But both Nigel and I have given you enough tutorial material for you to figure this out on your own. Perhaps you might tell us what your business case is. Also try it on your own and post your code with comments about your approach.

If you fail, this is great! Point out what line fails and explain what you attempted to do! Failing is learning.

   

Already done and thanks for the info... I went back to Pauls app (UnWrap) for reference examples and I got my apps function to work as I expected. Now to make it look nicer...

   

My switch case exceeds the limit of the web site so I can't post the whole code. The code accepts a breed and sex for the dog and then takes those two Strings combines them and returns a double for the ideal weight for the entered dog and its sex... Theres probally a more efficent way of doing this but oddly this works as expected.

 Button("Press to get ideal weight for \(name)"){
                idealWeight = dogweight(dogbreed: breed, dogsex: sex)
                }
                .buttonStyle(.borderedProminent)
                .font(.footnote)

                func dogweight(dogbreed: String, dogsex: String) -> Double {
        print(dogbreed)
        print(dogsex)
        let dog = dogbreed + "," + dogsex
        print(dog)
        switch dog {
    case "Affenpinscher,male":
        idealWeight = 10.0
    case "Affenpinscher,female":
        idealWeight = 10.0
    case "Afghan Hound,male":
        idealWeight = 60.0
    case "Afghan Hound,female":
        idealWeight = 60.0
    case "Airedale Terrier,male":
        idealWeight = 70.0
    case "Airedale Terrier,female":
        idealWeight = 70.0
        default:
            idealWeight = 10.0
        }
        print(idealWeight)
        return idealWeight
    }

}

   

Nice. Thanks for posting code.

It's time to consider views. As much as you can, think of views as ways to project onto a screen the contents of a struct that just holds data. Review your code and think about removing struct code that executes business rules.

For example, finding the ideal weight of a breed, based on gender. The view should not concern itself with this! The view should focus on displaying the ideal weight, the gender, and the dog's breed. Doing the calculations is someone else's business!

Here's a different way to approach your business problem. Paste into Playgrounds, and play around with the business rules.

// Paste into Playgrounds.
// Notice how business rules are built into the struct.
struct Dog {
    enum DogGender {  // Business rule! Only two genders. Perhaps consider neutered?
        case male, female
    }
    var breed: String     = "Pug"
    var gender: DogGender = .female
    var idealWeights      = (male: 10.0, female: 8.5) // Tuple holds ideal weights for BOTH genders

    // Business rule!
    // A dog struct should encapsulate its business rules in one place.
    // Don't rely on the View to know the intricate details of extracting ideal weights.
    // This function extracts the healthy weight for a selected gender.
    func idealWeight(forGender gender: DogGender) -> Double {
        // return ideal weight for breed's gender
        return gender == .male ? idealWeights.male : idealWeights.female
    }
}

// Notice how you store BOTH male and female ideal weights.
let commonDogs =  [ Dog(breed: "Affenpinscher",    idealWeights: (18,   12.0)),
                    Dog(breed: "Afghan Hound",     idealWeights: (22.3, 20.4)),
                    Dog(breed: "Airedale Terrier", idealWeights: ( 7,    6.0)),
                    Dog(breed: "English Springer", idealWeights: (10.2,  7.0)),
                    Dog(breed: "Boxer",            idealWeights: (12.7, 12.1)),
                    Dog(breed: "Mastiff",          idealWeights: (23.6, 20.1)) ]

// Find a certain breed.
var foundDog = commonDogs.first { $0.breed == "English Springer" }
if let dog = foundDog {
    print ("A healthy male \(dog.breed) should weigh \(dog.idealWeight(forGender: .male)) parsnips.")
}

// Find a different breed and gender.
foundDog = commonDogs.first { $0.breed == "Mastiff" }
if let dog = foundDog {
    print ("A healthy female \(dog.breed) should weigh \(dog.idealWeight(forGender: .female)) parsnips.")
}

// Find a different breed and gender.
foundDog = commonDogs.first { $0.breed == "Kansas City BBQ Hound" }
// Not found! So ignore the print statement.
if let dog = foundDog {
    print ("A healthy female \(dog.breed) should weight \(dog.idealWeight(forGender: .female)) parsnips.")
}

Thanks to @rooster for capitalization reminders.

   

So is this portion of the code whats called a dictionary?

let commonDogs =  [ dog(breed: "Affenpinscher",    idealWeights: (18,   12.0)),
                    dog(breed: "Afghan Hound",     idealWeights: (22.3, 20.4)),
                    dog(breed: "Airedale Terrier", idealWeights: ( 7,    6.0)),
                    dog(breed: "English Springer", idealWeights: (10.2,  7.0)),
                    dog(breed: "Boxer",            idealWeights: (12.7, 12.1)),
                    dog(breed: "Mastiff",          idealWeights: (23.6, 20.1)) ]

   

This is orthogonal to the question at hand, but:

struct dog {
    enum dogGender {  // Business rule! Only two genders. Perhaps consider neutered?

In Swift, you should really name your types starting with a capital letter. That's the convention and that's what will make sense to other people reading your code.

So:

struct Dog {
    enum DogGender {
        ...
    }
    ...
}

So is this portion of the code whats called a dictionary?

That's actually an array of dog structs.

   

Array

No, this portion of code is a collection of dogs. This collection is actually an array of Dog structs. The array is named commonDogs and has six Dog structs.

If you want to find a particular breed, you have to search each Dog struct in the array for Boxer, or for Mastiff. Arrays have a nice function to help you called first(where:)

See-> Array functions

You provide a test, and the array function will find the first element in the array where the test is true.
I used it to find the first element in the array where the breed is English Springer. Of course, the element may not be in the array, so it will return nil.

Dictionary

Think of a common dictionary. You want to know the definition of cromulent? Well, you use that word as a key and flip through the pages until you find the entry that matches that key. There you will find the word's definition.

// Paste into Playgrounds.
// Just like a normal dictionary, you have 'terms' (called Keys) and definitions.
var dogDictionary =  ["English Springer": (male: 10.2, female:  7.2),
                      "Boxer":            (male: 12.7, female: 12.1),
                      "Mastiff":          (male: 23.6, female: 20.1)]

Notice these are not structs. There is a string that is the dictionary's key. Followed by a tuple which is the key's definition.

// Like a regular dictionary, you look up the definition by finding the term (key)
// Look for "Weiner" in the dictionary. It may NOT be in the dictionary!
dogDictionary["Boxer"]!.male
dogDictionary["Mastiff"]!.female
dogDictionary["Weiner"] // should be nil

Do you want to add a new term to your dogDictionary? You can add a new term to the dictionary like this:

// Add new ideal weights for a Weiner dog.
dogDictionary["Weiner"] = (male: 6.5, female: 6.2)  // assign definition to a new term
dogDictionary["Weiner"] // now you can find this term in your dictionary.

   

Someone once told me if you don't ask stupid questions you just stay stupid... I think I've exceeded my limit thanks for your help and examples.

   

Rodney makes an observation about limits within the HWS forums:

Someone once told me if you don't ask stupid questions you just stay stupid...
I think I've exceeded my limit thanks for your help and examples.

Rodney: You're welcome.

Good Luck!

I hope I didn't give you any impressions that I thought your questions were stupid. I enjoy answering questions and thinking of detailed answers. I enjoy thinking of different ways to explore and explain Swift, design, or architecture concepts that may give new developers heartache. However I've received feedback that my answers are perceived to be condescending, perhaps snarky. I want to remove heartache, not cause it.

I wish you luck on your journey. I will probably be taking a break.

   

No offence taken I was just attempting a little humor didn't mean to offend... I had actually tried a Function with two strings before your I saw your answer but am always amazed at many ways a problem can be solved. I appreciate the help on this forum as it expands my knowledge in the process.

   

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.