4

In the Swift Programming Language book it explicitly states:

You can't use subscript syntax to append a new item to the end of an array

The example provided in the book also states that even if the replacement set of values has a different length than the range you are replacing it is fine. So for example:

var shoppingList = ["Eggs", "Milk", "Chocolate"]
shoppingList[0...2] = ["Bananas", "Apples"]
// shoppingList = ["Bananas", "Apples"]

which makes sense because you are replacing 3 values with the values of Banana and Apple. However, if we did this instead:

var shoppingList = ["Eggs", "Milk", "Chocolate"]
shoppingList[0...2] = ["Bananas", "Apples", "Sausage", "Pear"]
// shoppingList = ["Bananas", "Apples", "Sausage", "Pear"]

I thought we were not allowed to use subscript syntax to append a new item to the end of the array, but this seems like a loophole in the language. Can someone explain to me why this happens and/if this is a valid behaviour or is a bug? Thanks!

2 Answers 2

3

A subscript is nothing else than a function without a name. It can do anything a function can -> modifying is is possible. As with every function though, if you're passing invalid parameters it will fail.

When using a subscript with an array like array[index] to set a new value, the array simple replaces the existing value with the input, so if you entered an index which doesn't exist yet, it cannot replace the value and will therefore fail.

The book was referring to something like

var array = [0, 1, 2]
array[3] = 3

which would give you an indexOutOfBounds error, because the index 3 doesn't exist yet and the subscript doesn't automatically add a new element.

Let's assume the implementation of this subscript would check to see if the index doesn't exist yet and adds it when needed. What could happen:

var array = [0, 1, 2]
array[100] = 3  // Index 100 doesn't exist -> But what to add at index 3 to 99?

Also every time you'd assign something to an array a check would have to be made which would be incredibly slow.

Sign up to request clarification or add additional context in comments.

Comments

3

When the book says “you can’t use subscript syntax to append a new item to the end of the array”, really what it means is, “the way Array.subscript (index: Int) -> T has been implemented, you can’t use it to append a new item to the end of the array”.

subscript is just a bit of syntactic sugar for a function with propertyish qualities that takes some arguments (in this case index) and either gets or sets a value (in this case T). But just like any function, what it does can be whatever you want. It could set the value at index, or it could fire the nuclear missiles if you wrote it that way.

As it happens, Array defines a second overload for subscript that operates on ranges, and that does have extending capabilities. But the book is referring specifically to the more conventional one that just takes a single index.

To demonstrate, here’s an extension to Array that defines another version of subscript, this time one that if you name the index extend:, will extend the array with the new value up to the desired index:

extension Array {
    // add a new subscript with a named argument
    subscript (extending index: Int) -> T {
        get { return self[index] }
        set(newValue) {
            if index < self.endIndex {
                self[index]
            }
            else {
                let extendBy = index + 1 - self.endIndex
                self.extend(Repeat(count: extendBy, repeatedValue: newValue))
            }
        }
    }
}

var a = [1,2,3]

a[extending: 5] = 100
// a is now [1, 2, 3, 100, 100, 100]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.