I'd like to write an extension for Array
which safely returns an unwrapped version of itself.
I can do it with a generic method like so:
func unwrapElements<T>(array: [T?]) -> [T] {
let filtered: [T?] = array.filter{ $0 != nil }
let unwrapped: [T] = filtered.map { $0! }
return unwrapped
}
And I can call it like this:
let sparseNames: [String?] = ["alice", "bob", nil, "doug", nil, nil, "george", "hubert"]
let names: [String] = unwrapElements(sparseNames)
where names
ends up being ["alice", "bob", "doug", "george", "hubert"]
and is safe to iterate and work with each element.
However, I want to call it like this:
let names = sparseNames.unwrapElements()
I've seen a few similar questions (like this one) but they don't address how to create the method as an extension.
(this is tagged with Xcode6.1 to denote the version of Swift I'm using)
Note: Swift 1.2 Beta 3 has introduced the flatMap
function which helps with optionally chaining arrays. See this excellent blog post here
You can't do this right now in Swift. To add that function as an extension to Array
, you'd have to mark somehow that it's only callable with certain kinds of arrays: those with optional values as the subtype. Unfortunately, you can't further specialize a generic type, so global functions are the only way possible.
This is the same reason Array
has a sort
method that takes a comparison function as a parameter, but it doesn't have a sort
that "just works" if the array is full of Comparable
members - to get that kind of function, you have to look at the top-level sort:
func sort<T : Comparable>(inout array: [T])