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

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'


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


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?


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")))


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.


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 )


@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


Save 50% in my Black Friday sale.

SAVE 50% To celebrate Black Friday, 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!

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.