Modifying a Struct Element in Array

I'm very new to xCode, so the answer to this might be easy 😝


In ContentView.swift I have the following struct:

struct day {
    //var id = UUID()
    var x1: Int
    var x2: Int
    var x3: Int
    var bal: Int
}


Then I make an array with it:

var week = [  day(x1: -1, x2:   0, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100)]


How do I modify it? This leads to error, telling me this type of code is not allowed in the top line of code:

week[1].bal = 111

Where else do I put it? My end goal is to make each bal = x1 + x2 + x3



Here's the entire code if you need the big picture:

import SwiftUI

struct day {
    //var id = UUID()
    var x1: Int
    var x2: Int
    var x3: Int
    var bal: Int
}

var starting = 2000
var week = [  day(x1: -1, x2:   0, x3: 0, bal:  100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100),
              day(x1: -5, x2: -10, x3: 0, bal: 100)]

//week[1].bal = 111

struct ContentView: View {
    var body: some View {
        
        VStack{
            Text("Name of Month")
            //Text(String(arrayname[2][3]))
            
            //Text(String(week[1].x1))
            
            //---------------drwaing a month------------------
            VStack{
                ForEach(0..<1){ row in
                    //-------------------drawing a week--------------------
                    Text("WEEK #" + String(row+1))
                    HStack{
                        ForEach(0..<7){ number in
                            VStack{
                                Text(String(week[number].x1)).font(.caption)
                                Text(String(week[number].x2)).font(.caption)
                                Text(String(week[number].x3)).font(.caption)
                                Text(String(week[number].bal))
                            }
                            
                            Spacer()
                            
                        }
                        
                    
                    }
                    //Spacer()
                    
                }
            }
            
            
        }
    }



}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

As the error message is explaining, an executable statement like this:

week[1].bal = 111 

needs to be somewhere inside some method or function.


To create a place to move it, you need to define when it should be executed.


If you want it executed at the initialization, you have no need to put such a statement:

struct Day {
    var x1: Int
    var x2: Int
    var x3: Int
    var bal: Int
}
var week = [
    Day(x1: -1, x2:   0, x3: 0, bal: 100),
    Day(x1: -5, x2: -10, x3: 0, bal: 101), //<-
    Day(x1: -5, x2: -10, x3: 0, bal: 100),
    Day(x1: -5, x2: -10, x3: 0, bal: 100),
    Day(x1: -5, x2: -10, x3: 0, bal: 100),
    Day(x1: -5, x2: -10, x3: 0, bal: 100),
    Day(x1: -5, x2: -10, x3: 0, bal: 100)
]

(In Swift, you should use capitalized names for types, so I changed `day` to `Day`.)


If you want to modify it later than the initilization, you need to clarify when.

"an executable statement like this needs to be somewhere inside some method or function."

- It sounds like youre right, but I don't know how to do that. I call it like this?

var week = [  
    Day(x1: -1, x2:   0, x3: 0, bal: 100),  
    Day(x1: -5, x2: -10, x3: 0, bal: 100),
    Day(x1: -5, x2: -10, x3: 0, bal: 100),  
    Day(x1: -5, x2: -10, x3: 0, bal: 100),  
    Day(x1: -5, x2: -10, x3: 0, bal: 100),  
    Day(x1: -5, x2: -10, x3: 0, bal: 100),  
    Day(x1: -5, x2: -10, x3: 0, bal: 100)  
]  
modify() // <--


and then I have the function:

function modify(){
     week[1].bal = 111 
}


where would I have to make the function? Is it in a seperate file?

So you see modify() is in the delacaration part of the code, not inside an executable.


Executables are functions, which may be:

- init methofs,

- IBActions

- other func


In your case, you could have something like this (you see modify may be called in different places ; here I show 2, just to illustrate):



class MyViewController: UIViewController {

//          Some IBOutlets probably

// declaration of properties
     var week = [
         Day(x1: -1, x2:   0, x3: 0, bal: 100),
         Day(x1: -5, x2: -10, x3: 0, bal: 100),
         Day(x1: -5, x2: -10, x3: 0, bal: 100),
         Day(x1: -5, x2: -10, x3: 0, bal: 100),
         Day(x1: -5, x2: -10, x3: 0, bal: 100),
         Day(x1: -5, x2: -10, x3: 0, bal: 100),
         Day(x1: -5, x2: -10, x3: 0, bal: 100)
     ]

     // If you need to modify when view loads
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        modify() // it is now inside a func
     }

     function modify(){
          week[1].bal = 111
     }

     // If you need to modify when some button is pressed
    @IBAction func doModification(_ sender: UIButton) {
        modify() // it is also inside a func

    }

}



Is that clear now ?


If so, don't forget to close the thread.

The method call `modify()` is another executable statement which needs to be somewhere inside some method or function.


Generally, there are some initialization point based on the framework you use.

If you use UIKit and you want to modify the instance properties of a view controller, `viewDidLoad()` would be a good point of initialization.


But, in your case you use SwiftUI and your `week` is a global variable, which you should avoid whether in UIKit or SwiftUI.


I recommend to declare a class containing `week` and define a method in the class.

import Foundation

struct Day {
    //var id = UUID()
    var x1: Int
    var x2: Int
    var x3: Int
    var bal: Int
}

class WeekModel {
    var starting = 2000
    
    var week = [  Day(x1: -1, x2:   0, x3: 0, bal:  100),
                  Day(x1: -5, x2: -10, x3: 0, bal: 100),
                  Day(x1: -5, x2: -10, x3: 0, bal: 100),
                  Day(x1: -5, x2: -10, x3: 0, bal: 100),
                  Day(x1: -5, x2: -10, x3: 0, bal: 100),
                  Day(x1: -5, x2: -10, x3: 0, bal: 100),
                  Day(x1: -5, x2: -10, x3: 0, bal: 100)]

    init() {
        modify()
    }
    
    func modify() {
        week[1].bal = 111
    }
}


And you can declare a property holding the instance in your View.

import SwiftUI

struct ContentView: View {
    var weekModel = WeekModel()
    
    var body: some View {
        VStack{
            Text("Name of Month")
            //Text(String(arrayname[2][3]))
            
            //Text(String(week[1].x1))
            
            //---------------drwaing a month------------------
            VStack{
                ForEach(0..<1){ row in
                    //-------------------drawing a week--------------------
                    Text("WEEK #" + String(row+1))
                    HStack{
                        ForEach(0..<7){ number in
                            VStack{
                                Text(String(self.weekModel.week[number].x1)).font(.caption)
                                Text(String(self.weekModel.week[number].x2)).font(.caption)
                                Text(String(self.weekModel.week[number].x3)).font(.caption)
                                Text(String(self.weekModel.week[number].bal))
                            }
                            Spacer()
                        }
                    }
                    //Spacer()
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


With this change, you can easily adopt @ObservedObject or @Environment easily in the future.

Have you ever got this error?

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions


trying to upload a screenshot here, how do i do that?

You cannot upload a screenshot. Just copy the expression.


The problem is often that the compiler has too many type inferences to do.

Either breaking the expression or providing explicit types for variables solve it.


But just post the line in reference.

Modifying a Struct Element in Array
 
 
Q