Chapter 12 Bronze Solution

Hello! Here is the code I used for my solution:

func greetByMiddleName(fromFullName name: (first: String, middle: String?, last: String)){

guard let middleName = name.middle else {
    print("Hey there!")
    return
}

guard middleName.count < 10 else {
    let middleInitial = middleName.first
    print("Hello, \(name.first) \(middleInitial!). \(name.last)!")
    return
}

print("Hey, \(middleName)!")
}
2 Likes

I’m at a loss for how to solve this in exactly the way the author seems to be asking. The challenge says you can have a guard statement with multiple clauses but I can’t find any examples of that, and the Swift documentation for the guard statement doesn’t seem to support doing that either.

I could write multiple guard statements as @Aphid035 did above but that doesn’t seem to be what they’re looking for. Or I could write a guard statement with multiple conditions, but that won’t produce the desired behavior.

As an example of what I mean, if I replaced the guard statement with an if statement I could have:

func greetByMiddleName2(fromFullName name: (first: String,
                                            middle: String?,
                                            last: String)) {
    if name.middle == nil {
        print("Hey there!")
        return
    }
    else if name.middle!.count > 10 {
        let middleInitial = name.middle!.first!
        print("Hey, \(name.first) \(middleInitial). \(name.last)")
        return
    }
    print("Hey, \(name.middle!)")
}

This has one if statement with 2 clauses for the two exceptions where you don’t print the middle name. I don’t see a way to have one guard statement that does the same thing, but that seems to be what’s expected.

I am also a little puzzled as well. Maybe they meant something like this?

func greetByMiddleName(fromFullName name: (first: String,
                                           middle: String?,
                                           last:String)) {
    guard let middleName = name.middle,
          let middleInitial = middleName.first else {
        print("Hey there!")
        return
    }
    
    if middleName.count <= 10 {
        print("Hey, \(middleName)")
    } else {
        print("Hey, \(name.first) \(middleInitial). \(name.last)")
    }
}

I don’t think the Guard function is explained very well in the text, but I did find a few references on the Internet that helped me formulate a solution that differs from the others posted here. Below is what I came up with:


Notes: 1. I added an optional, “length,” to capture the length of the middle name; 2. the length is checked in the second guard condition; 3. I used the “String(describing:)” clause to remove a warning that appeared regarding string interpolation; and 4. I included two statements at the end to test both cases and show that a middle name with less than 12 (ooops–should have been 10) characters works as desired.`

If length is not used elsewhere, there is no need for a separate variable:

var length: Int? = name.middle?.count

Instead, write the guard statement like this:

guard let middleName = name.middle, middleName.count <= 12 {
    ...
}

The previous post and the very first post in this thread are good (canonical) examples of how to use a guard statement.

In addition to unwrapping an optional variable and making it available for later use, a guard statement can also be used to enforce a requirement:

func mass (of planet: String) -> Double? {
   ...
}

let planet = "Bong"
let mass   = mass (of: planet)

guard let mass else {
   print ("mass of planet `\(planet)` not available")
   return
}

guard mass >= 0 else { 
   fatalError ("invalid mass")
}

By the way, instead of a screenshot, you can copy and paste your code between a pair of three back-tick characters (```) like this:

```
Paste your code here
```

For example:

func foo () -> Bar {
   ...
}

Hello! Here is my solution, I unwrapped name.middle because to my understanding it is protected by the guard statement. This removes Optional(“_____”) when printing.

I’m not sure if “additional clauses” means inline or create another guard statement, so I went with inline.

I got confused on how the else statement works in conjunction with a print outside of the guard, but I think this is the best output in terms of exactness. They asked for the generic greeting which used no names at all.

func greetByMiddleName (fromFullName name: (first: String, middle: String?, last: String)){
    guard let middleName = name.middle, middleName.count < 4 else {
        print("Hey, \(name.middle!)!")
        return
    }
    print("Hey there!")
}

greetByMiddleName(fromFullName: (first: "John", middle: "Adam", last: "Smith"))