11 Replies
Latest reply: Aug 6, 2015 6:32 AM by dhoerl
Level 1 (0 points)

I have a large cascading let - and midway through I'd like to make one assignment that's not an optional:

```var b = [String: [ [String: Int]] ]()
if let a = b["foo"]  where a.count > 0,
let c = a[0], // ** FAILS - not an optional assignment
let d = c["Howdie"] where d > 5
{
}
```

I'm finding more and more that I have this case. Now, I can just go use a[0] everywhere instead of the desired 'c', but the code is harder to read, and often in the body of the if I need 'c' too.

I know I could "hack" a way by making my code more complex - that is, instead of looking for an array of [String: Int], I could use [String: Any] instead,:

```var b = [String: [ [String: Any]] ]()
if let a = b["foo"]  where a.count > 0,
let c = a[0] as? [String: Int], // OK
let d = c["Howdie"] where d > 5
{
}
```

Is there something I'm missing? [Sigh, often is :-) ]

• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 3 (110 points)

If you are using Swift 2.0, I think the new guard let construct may offer a solution for you.

```guard let a = b["foo"] where a.count > 0 else { return }     // you can bail by throwing, return, break, continue as appropriate
let c = a[0]
guard let d = c["Howdie"] where d > 5 else { return }
```
• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 3 (150 points)

Yes. You must use a label to break out of a do block.

```d: do {
guard let a = b["foo"] where a.count > 0 else {break d}
let c = a[0]
if let d = c["Howdie"] where d > 5 {}
}
```
• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 7 (3,325 points)

If else-omitted guard could break the closest code-block (is this once discussed?), it would be more preferrable than the complicated if-let syntax:

```do {
guard let a = b["foo"] where a.count > 0
let c = a[0]
guard let d = c["Howdie"] where d > 5
//...
}
```
• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 1 (0 points)

Can you modify this example to show how the "else" clause is handled? That said, I can use your 'case':

```guard let a = bb["foo"] where a.count > 0,
case let c = a[0],
let d = c["Howdie"] where d > 5
else { fatalError("Yikes") }
```

Thank you ever so much for this assistance! I'd just never thought of it!

[ I'm constantly reminded of how there is so much more to learn about Swift, even though I've used it exclusively since last June. ]

• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 7 (3,325 points)

It's me to thank you. Until you addressed the issue, I never thought of using if-case in this way. (Code shown by Jessy was my preferred style.)

• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 7 (3,325 points)

How is this?

```if let a = b["foo"]  where a.count > 0,
case let c = a[0],
let d = c["Howdie"] where d > 5
{
//...
}
```
• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 3 (150 points)

I had no idea that "case" could do that. That doesn't seem much like a "case"!

• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 1 (0 points)

I am going to guess that since 'case' is pattern matching, case can by design fail. However, this usage is sort of like using '*' in a regular expression - the assignment always succeeds.

• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 2 (40 points)

Why not just use ".first" instead of [0]? This gets you a result which is optional, allowing you to do this without using case. You also don't need the "where" clause on the assignment of a, since if count is equal to 0, a.first will simply return nil.

```var b = [String: [ [String: Int]] ]()
if let a = b["foo"],
let c = a.first,
let d = c["Howdie"] where d > 5
{
}
```
• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 3 (150 points)

Now that we know about case, that's an efficiency drop, but if a isn't needed,

```if let c = b["foo"]?.first

```

works.

• ###### Re: Any clever way to add a simple assignment in a cascading if "let"?
Level 1 (0 points)

The code I posted is contrived - the index could be arbitrary (one viewController from an array - think tabBarController or splitViewController). But I was interested in a general solution, not just something that works just for my contrived example - case is it.