UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How to store multiple iterations of a data structure into an array? The end goal is to ForEach loop through that array to display the data in a view

Forums > Swift

Here is the GitHub repository which contains the iOS app files and also a MacOS Command Line Tool file.

Purpose of the app: Calculate yearly income based on established pay scales and multiple promotions in future years.

The Command Line Tool code was the test bed and works great. It produces the following print:

Years since hired: 3
Department(s) for Year 3: Sanitation
Earnings for Year 3: 19200
Age: 57

Years since hired: 4
Department(s) for Year 4: Sanitation
Earnings for Year 4: 23040
Age: 58

Years since hired: 5
Department(s) for Year 5: Sales
Earnings for Year 5: 46080
Age: 59

Years since hired: 6
Department(s) for Year 6: Sales,Management
Earnings for Year 6: 59520
Age: 60

Years since hired: 7
Department(s) for Year 7: Management
Earnings for Year 7: 72960
Age: 61

Years since hired: 8
Department(s) for Year 8: Senior Management
Earnings for Year 8: 96000
Age: 62

Years since hired: 9
Department(s) for Year 9: Senior Management
Earnings for Year 9: 99840
Age: 63

Years since hired: 10
Department(s) for Year 10: Senior Management
Earnings for Year 10: 103680
Age: 64

Years since hired: 11
Department(s) for Year 11: Senior Management
Earnings for Year 11: 53760
Age: 65

I am attempting to transition from this Command Line Tool code to a iOS app. I want the above print content (year group, department, earnings and age) to be displayed in the iOS app ResultsView. The current ResultsView displays notional sample data in a desirable ScrollView format.

In order to replace the notional sample data array with actual app user-input data, I expect a new array of year group, department, earnings and age must be generated within the EmployeeViewModel in accordance with the following information:

@Published var userData: Employee =
    Employee("Charlotte Grote",
             birthdate: DateComponents(calendar: .current, year: 1965, month: 7, day: 20).date!,
             hiredate: DateComponents(calendar: .current, year: 2021, month: 12, day: 28).date!,
             yearGroup: 1,
             retirementAge: 65,
             department: .other("Sanitation"),
             monthlyHoursWorked: 160,
             planningToPromote1: true,
             planningToPromote2: true,
             planningToPromote3: true,
             planningToPromote4: true,
             promotion1Date: DateComponents(calendar: .current, year: 2023, month: 12, day: 28).date!,
             promotion2Date: DateComponents(calendar: .current, year: 2025, month: 6, day: 28).date!,
             promotion3Date: DateComponents(calendar: .current, year: 2026, month: 12, day: 28).date!,
             promotion4Date: DateComponents(calendar: .current, year: 2027, month: 12, day: 28).date!,
             secondDepartment: .other("Hospitality"),
             thirdDepartment: .other("Sales"),
             fourthDepartment: .other("Management"),
             fifthDepartment: .other("Senior Management"),
             regularPayRateIncreases: true,
             regularPayRateIncreasePercentage: 4,
             regularPayRateIncreaseYearInterval: 4)

    var firstDeptMonths: Int { Calendar.current.dateComponents([.month], from: userData.hiredate, to: userData.promotion1Date).month! }
    var secondDeptMonths: Int { Calendar.current.dateComponents([.month], from: userData.promotion1Date, to: userData.promotion2Date).month! }
    var thirdDeptMonths: Int { Calendar.current.dateComponents([.month], from: userData.promotion2Date, to: userData.promotion3Date).month! }
    var retireDate: Date { Calendar.current.date(byAdding: .year, value: userData.retirementAge, to: userData.birthdate)! }
    var fourthDeptMonths: Int { Calendar.current.dateComponents([.month], from: userData.promotion3Date, to: retireDate).month! }

Once an array of the years since hired, income, departments and age is compiled, I should be able to interate through the array with a ForEach to replace the sample data in the ResultsView.

Can you assist in creating a new userData array?

2      

In my GitHub repository MacOS code, there is the following function:

func yearlyDepartmentsEarnings() -> [(String, Decimal)] {
        let yearlyDepartments = yearlyDepartments()
        let yearlyEarnings = yearlyEarnings()
        let yearlyDepartmentsEarnings: [(departments: String, earnings: Decimal)] =
        Array(zip(yearlyDepartments, yearlyEarnings))
        return yearlyDepartmentsEarnings
    }

This successfully stores the yearly department and income data into an array.

I've updated the ResultsView to use the above function to create an table of departments and income:

import SwiftUI

struct SampleData: Identifiable {
    let yearGroup: Int
    let age: Int
    let department: String
    let income: Int
    let id = UUID()
}

private var employeeData: [SampleData] = [
    SampleData(yearGroup: 1, age: 35, department: "Sales", income: 50000),
    SampleData(yearGroup: 2, age: 36, department: "Sales", income: 55000),
    SampleData(yearGroup: 3, age: 37, department: "Sales", income: 60000),
    SampleData(yearGroup: 4, age: 38, department: "Sales", income: 65000),
    SampleData(yearGroup: 5, age: 39, department: "Sales", income: 70000),
    SampleData(yearGroup: 6, age: 40, department: "Management", income: 150000),
    SampleData(yearGroup: 7, age: 41, department: "Management", income: 160000)
]

private var employeeData2: [(String, Decimal)] = [
    yearlyDepartmentsEarnings()    //<- error here
]

struct ResultsView: View {
    @EnvironmentObject var vm: EmployeeViewModel
    @Binding var tabSelection: Int

    var body: some View {
        ScrollView {
            VStack{
                HStack{
                    Spacer()
                    VStack(alignment: .leading) {
                        Text("Year")
                            .font(.title3)
                            .bold()
                        ForEach(employeeData) { worker in
                            Text("\(worker.yearGroup)")
                        }
                    }
                    Spacer()
                    VStack(alignment: .leading) {
                        Text("Age")
                            .font(.title3)
                            .bold()
                        ForEach(employeeData) { worker in
                            Text("\(worker.age)")
                        }
                    }
                    Spacer()
                    VStack(alignment: .leading) {
                        Text("Department")
                            .font(.title3)
                            .bold()
                        ForEach(employeeData) { worker in
                            Text("\(worker.department)")
                        }
                    }
                    VStack(alignment: .leading) {
                        Text("Income")
                            .font(.title3)
                            .bold()
                        ForEach(employeeData) { worker in
                            Text("$\(worker.income)")
                        }
                    }
                    Spacer()
                }
                HStack{
                    Spacer()
                    VStack(alignment: .leading) {
                        Text("Department")
                            .font(.title3)
                            .bold()
                        ForEach(employeeData2) { worker in
                            Text("\(worker.department)")
                        }
                    }
                    Spacer()
                    VStack(alignment: .leading) {
                        Text("Income")
                            .font(.title3)
                            .bold()
                        ForEach(employeeData2) { worker in
                            Text("$\(worker.income)")
                        }
                    }
                    Spacer()
                }
            }

        }
    }
}

struct ResultsView_Previews: PreviewProvider {
    static var previews: some View {
        ResultsView(tabSelection: .constant(3))
            .environmentObject(EmployeeViewModel())
    }
}

However, the following complier error is presented:

Cannot find 'yearlyDepartmentsEarnings' in scope

2      

I can explain why you're getting a compiler error. Your yearlyDepartmentsEarnings function is part of the Employee struct.

But you call yearlyDepartmentsEarnings like it is a global function that is not part of a struct.

private var employeeData2: [(String, Decimal)] = [
    yearlyDepartmentsEarnings()    //<- error here
]

You need to create an instance of Employee and use that instance to call yearlyDepartmentsEarnings.

var employee: Employee
private var employeeData2: [(String, Decimal)] = employee.yearlyDepartmentsEarnings()

You do not declare any Employee instances anywhere in your code listing so I cannot tell you where you should create an Employee instance in your app's code.

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.