UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Don't mistake map on an Optional instance for map over a Collection

Forums > Swift

What is the reason for this?

Xcode Quick Help tells me - that firstIndex(of element: String) -> Int? but in this example I need to map over a collection resulting from firstIndex(of:) instead of a single Int value wrapped in an Optional, as seemingly Array<String>.Index? is a.k.a. Int?

let arr = ["Iain", "Katie", "Eve", "Jess"]
var s = arr.firstIndex(of: "Eve").map{String($0)} ?? "Not found!"

According to the Xcode warning when I try print(arr.firstIndex(of: "Eve")):

Expression implicitly coerced from 'Array<String>.Index?' (aka 'Optional<Int>') to 'Any'

3      

It's an Optional Int because it returns the first index where the corresponding element can be found, but if that element isn't in the array at all it will return nil.

as seemingly Array<String>.Index? is a.k.a. Int?

Yes, if you look at the source for Array, you will see the line: public typealias Index = Int

3      

Thanks @roosterboy : It's the Index? part that is a.k.a. Int? - that's clearer.

But the question still remains why I need to map over the collection resulting from firstIndex(of:) rather than process a single Int? value?

Xcode Quick Help tells me - that firstIndex(of element: String) -> Int?

3      

You don't need to map over it. The result of firstIndex(of:) is an Int?, and you can use it in any way you use an optional Int. If you're thinking you need to map because of the warning you get from print, that's very specifically about the internals of how print works (which I go into here). If you use the result anywhere other than print, you won't get that warning.

Xcode gives you multiple options to avoid the warning, including nil coalescing as you did in your map closure:

print(arr.firstIndex(of: "Eve") ?? "Not found!") // No warning

If you want the debug description of the optional and don't want to coalesce, then you can provide print a String:

print(String(describing: arr.firstIndex(of: "Eve")))

3      

There is no collection. The result returned from firstIndex(of:) is an Optional, which has its own map method. Using this method allows you to get at the wrapped value inside the Optional. There are other ways you could do the same thing.

And, if you think about it, how could firstIndex(of:) return a collection anyway? There can only be one first index, after all.

3      

Yes, got it!

  1. I mistook map on an Optional instance for map over a Collection ... due, I expect, from habits developed writing in other languages
  2. I mis-read not-entirely-directly-related warning from print() as confirmation of my mistake in 1.

Well, that was an interesting journey! Thaks to all those who helped me learn that lesson! (@roosterboy and @bbatsell )

3      

@twostraws  Site AdminHWS+

@iainhouston: If you click the checkmark next to the answer that helped, the system will add the "SOLVED" title for you, and also mark the answer green to help others find it

3      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.