Swift subscripts

A portrait painting style image of a pirate holding an iPhone.

by The Captain

on
May 16, 2023

Subscripts in Swift: Simplifying Collection Access

Subscripts in Swift are shortcuts for accessing elements of a collection, list, or sequence. Like functions, we can implement our own subscripts in custom types. In this tutorial, we'll explore how to implement subscripts in your own Swift classes and structs to simplify collection access!

What Are Subscripts?

Subscripts are shortcuts for accessing elements of a collection, list, or sequence. They provide a convenient and easy-to-read syntax for accessing elements at a specific index or key. You've probably already used subscripts before when accessing elements of an array or dictionary:

let array = [1, 2, 3]
let firstElement = array[0]

let dictionary = ["name": "John", "age": 30]
let johnsAge = dictionary["age"]}

As you can see, subscripts use square brackets with an index or key inside to access an element in a collection. But did you know that you can also create your own subscripts in Swift?

Implementing Subscripts in Custom Types

Let's say we have a custom type called `Person` that stores a person's name, age, and occupation. We could use subscripts to access the person's properties with a more convenient and readable syntax:

struct Person {
  let name: String
  let age: Int
  let occupation: String

  subscript(key: String) -> String? {
    switch key {
      case "name": return name
      case "age": return String(age)
      case "occupation": return occupation
      default: return nil
    }
  }
}

In this example, we've created a subscript that takes a `String` key and returns an optional `String`. This subscript first checks the key passed in, and returns the corresponding value from the `Person` struct.

We can now use this subscript to access a `Person`'s properties:

let john = Person(name: "John", age: 30, occupation: "Developer")
let name = john["name"] // "John"
let age = john["age"] // "30"
let occupation = john["occupation"] // "Developer"
let favoriteColor = john["favoriteColor"] // nil}

As you can see, we've now simplified accessing the `Person` struct properties by using subscripts. We can access any property by using a key instead of having to remember the property names and call them explicitly.

Using Subscripts for Mutating Collections

Subscripts aren't just for reading values from collections - they can also be used to modify collections. Let's say we have a custom type called `ShoppingList` that stores a list of items as an array:

struct ShoppingList {
  var items: [String]

  subscript(index: Int) -> String {
    get {
      return items[index]
    }
    set(newValue) {
      items[index] = newValue
    }
  }
}

In this example, we've created a subscript that takes an `Int` index and returns a `String` element from the `items` array. We've also implemented a setter for the subscript that allows us to modify the element at the specified index:

var list = ShoppingList(items: ["Eggs", "Milk", "Bread"])
list[1] // "Milk"
list[1] = "Juice"
list.items // ["Eggs", "Juice", "Bread"]}

We can now easily modify the `ShoppingList` by using subscripts in a way that's both simple and intuitive.

Conclusion

Subscripts are a powerful feature in Swift that allow you to simplify and customize element access in your own custom types. By implementing subscripts, you can make your code more readable and concise, and allow for intuitive modification of your collections.