Richard Topchii
Richard Topchii

Reputation: 8195

Swift Array: subscript with IndexPath - unable to mutate

I'd like to add an extension to array of arrays to retrieve an Element with the IndexPath of size 2:

let array: [[String]] =  ....
let indexPath = IndexPath(indexes: [0, 0])
let string = array[indexPath]

I'm getting an error cannot assign through subscript subscript is get-only while implementing the following extension:

extension Array where Element : Collection, Element.Index == Int {
  subscript(indexPath: IndexPath) -> Element.Iterator.Element {
    get {
      return self[indexPath.section][indexPath.item]
    }
    set {
      self[indexPath.section][indexPath.item] = newValue
    }
  }
}

What is the reason for such an error? How can I add a mutation option to the subscript?

Upvotes: 3

Views: 1270

Answers (1)

Martin R
Martin R

Reputation: 539955

In order to mutate the nested arrays you have to require that

Element : MutableCollection

instead of Element : Collection.

You can also define two extensions: a read-only subscript for read-only collections, and a read-write subscript for mutable collections:

extension Collection where Index == Int, Element : Collection, Element.Index == Int {
    subscript(indexPath: IndexPath) -> Element.Iterator.Element {
        return self[indexPath[0]][indexPath[1]]
    }
}

extension MutableCollection where Index == Int, Element : MutableCollection, Element.Index == Int {
    subscript(indexPath: IndexPath) -> Element.Iterator.Element {
        get {
            return self[indexPath[0]][indexPath[1]]
        }
        set {
            self[indexPath[0]][indexPath[1]] = newValue
        }
    }
}

Upvotes: 8

Related Questions