Generic Extensions on Arrays

Prerequisites

Please make sure you watch first the following prerequisite videos:

So what are generic extensions on arrays? Let’s discuss…

We learned last time that, since arrays are actually structs under the hood in Swift, we can write extensions on arrays in order to add new custom functionality. Here we have isSingle from last time, an example of a computed property added to arrays through an extension. As soon as we wrote this, all arrays in our project scope will respond to this call by returning a boolean value, true if the the array has only one element, and false otherwise.

But what if, instead of wanting a boolean value, we actually want the element in the array, if and only if that element is indeed the only single element in the array? We got a problem here, don’t we? This computed property will need to have a return type, but what would that be? It was easy when we wrote isSingle, which returns a boolean value, a known foundation data type. This time we want to return an actual element from the array, but we are in an array extension. We have no clue what type of elements our array contains. Are we dealing with integers, with doubles, strings, booleans, or some custom structs of our own?

We don’t know, but the array itself does, and from the array’s perspective, that type is called Element. This is a generic type, and for each instance of an array, this data type is a different, concrete, data type. So for an array of integers, this Element will be Int, and for an array of strings, this Element will be String, and so on.

We have to add a question mark here, though. Because our new computed property will only sometimes return an element. Only when this element exists as the only single element in the array. Otherwise, the property will return nil, which makes this an optional value.

So what about the implementation for our property? Well, we need to return an element if and only if the array only contains one single element, so a conditional statement is appropriate here: if isSingle. Note how we are making use of another property we wrote ourselves earlier in the array extension, which is perfectly valid here.

In this case, when isSingle returns true, what should we return? We can return first, which is a property provided by Apple on all arrays, which returns the first element in the array, if it exists, otherwise it returns nil.

Let’s take a look at the documentation. .first returns an optional element (notice the question mark), and this element is the generic data type we talked about earlier. Since we want to return whatever the property first returns, we need to make sure our own property has exactly the same return type.

And it does; our property also returns an optional generic Element. So we are good. In the case we already know our array contains one single element, we return the first element, which in this case will be the one and only element.

What to do when the array is empty, or when the array has more than one element? This would be the else case. In this case, we will simply return nil. We can do that, because our closure returns an optional value, and nil is a valid value for an optional.

And there you have it. We just created a generic computed property in an array extension. Since arrays are already designed to work with generic data types, so that they can store anything a project needs, all we had to do was to find out what that generic type is called. For each different data structure provided by Apple, the generic type has a different name. For arrays, it is called, naturally, Element.