Swift code not working

This is the code I'm having problems with:


for i in (1...pizzaNames.count).reversed() {
    pizzaNames.swapAt(i, i - 1)
}

I'm.getting the error out of range.

Swift indices start at 0. Use 0..<pizza.count or 0...pizza.count -1

Edit: You code should indeed start at 1 but end at count -1

Prefer ..< instead of subtratcting 1 from the right side. Otherwise, you risk getting 1...0 (for an empty array), which goes :firecracker:

Better yet, pizza.indices totally side-steps the problem

3 Likes

Empty pizza array would still kaboom on "1 ..< pizzaNames.count" line.

How would you write this code with "pizza.indices" ? You'll need to use slicing?

Only if pizza is specifically an Array.

In general, the indices property of a collection may hold a reference to the collection itself.

The documentation of indices specifically mentions that mutating a collection in a loop over its indices can cause an unintended copy of the entire collection, and recommends using a while loop instead, manually advancing an index.

• • •

However, for the code snippet shown in the original post, its intended effect appears to be simply to remove the last element and insert it at the beginning, so no loop is needed at all.

3 Likes

Thanks guys, got it working, there was a bug in Swift playground.

var pizzaNames = [1, 2, 3]

for i in pizzaNames.indices.reversed() {
    // ...
}

Though the body of your loopp will still crash. Could you elaborate on what exactly you're trying to do? I think you're trying to reverse the elements of pizzaNames, but I'm not sure.

As Nevin says, it looks like he's trying to rotate the elements of his array forwards with the last element moving to the beginning of the array. Like rotating the bits of an integer.

It's hard to say for sure without benchmarking it, but it looks like:

pizzaNames.insert(pizzaNames.removeLast(), at: 0)

Not only reads better, but also produces better code. Either way, I wouldn't use indices for this.

1 Like