How to Call a Setter for Subscript to Update Array

Hi all - I have a button that when pressed should use the …subscript… notation to call the setter function - but I don’t know how to code it below is the code for the struct of the Array of a custom struct called Letters:

In playground it works which makes me think it’s a scoping issue having the call in the Button portion of the code…


struct LetterGrid {

let rows = 6
let columns = 5


var grid: [Letter]

init(rows: Int, columns: Int) {
    grid = Array(repeating: Letter(isMatchedYellow: false, isMatchedGreen: false, letterText: Text("O")) , count: rows * columns)
}

func indexIsValid(row: Int, column: Int) -> Bool {
    return row >= 0 && row < rows && column >= 0 && column < columns
}

subscript(row: Int, column: Int) -> Text {
    get {
        assert(indexIsValid(row: row, column: column), "Index out of range")
        return grid[(row * columns) + column].letterText
    }
    set {
        
        assert(indexIsValid(row: row, column: column), "Index out of range")
        grid[(row * columns) + column].letterText = newValue
        
    }
}

}

and the code I have in the button:


Button(action: {

            var thisLetter = letterGrid[0,0]
            thisLetter = Text("Q")
            renderView()

            
        }, label: {
            Text("Letter")

@MplsRich

It’s not clear to me what you are trying to do and I am not familiar with subscript either. In fact this is the first time I have ever heard of it.

What View code do you have that shows how it works and what does renderView() do?

Can you share your entire playground code so that we can see what you are trying to do. Include the definition of the struct or class Letter.

Except for using Letter instead of Double and hard-coding the number of rows and columns, your code is exactly the same as the example given in the Swift docs, so I don’t see any immediately apparent reason why it wouldn’t work. I agree with Chris that we need to see some more code.

@Chris_Parker, check out the Subscripts page in the Swift documentation for how to do custom subscripts. They can be pretty useful. In fact, I used one in this answer I posted just the other day.

@roosterboy
Thank you. This may take some time to digest.

Thanks for both of you for responding. I finally figured it out - the problem was that I didn’t know how to call the ‘setter’ function - I did lift the code from the Swift documentation re subscript - below is the full code on playground and it works

import SwiftUI

struct LetterGrid {

let rows = 6
let columns = 5


var grid: [Letter]

init(rows: Int, columns: Int) {
    grid = Array(repeating: Letter(isMatchedYellow: false, isMatchedGreen: false, letterText: Text("U")) , count: rows * columns)
}

func indexIsValid(row: Int, column: Int) -> Bool {
    return row >= 0 && row < rows && column >= 0 && column < columns
}

subscript(row: Int, column: Int) -> Text {
    get {
        print("Get is called")
        assert(indexIsValid(row: row, column: column), "Index out of range")
        return grid[(row * columns) + column].letterText
    }
    set {
        print("Set is Called")
        assert(indexIsValid(row: row, column: column), "Index out of range")
        grid[(row * columns) + column].letterText = newValue

    }
}

}

struct Letter: Identifiable {
var isMatchedYellow = false
var isMatchedGreen = false
var letterText:Text
var id = UUID()

}
var myLetterGrid = LetterGrid(rows: 6, columns: 5)

myLetterGrid[0,0]

myLetterGrid[0,0] = Text(“P”)
myLetterGrid[0,1]

The app I’m working on is Wordle - I’m doing this as a practice app to get back into coding - this is not a commercial project, but rather a bit of a challenging app to figure out and practice on.

So the issue I was having on the app was one of scope - so I added @State to the variables that were supposed to call the setters for the array-

So the issue I was having on the app was one of scope - so I added @State to the variables that were supposed to call the setters for the array-