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

SOLVED: Playground: Troubleshooting function to create an array of hourly pay rates from employee history of promotions

Forums > Swift

Purpose of project: allow an employee to calculate/project future income based on several future promotions. With promotions come pay raises.

Current challenge to overcome: Create an array in which each element represents the average hourly payrate of that year.

The below employee example worked in the following departments: First year: Sanitation (other) Second year: Hospitality (other) Third & fourth years: Sales Fifth year: Management Sixth through eighth years: Senior Management

These are their repsective payscales:

sales: rates = [20,22,24,26,28,30,32,34,36,38,40]
management: rates = [30,32,34,36,38,40,42,44,46,48,50]
seniorManagement: rates = [40,42,44,46,48,50,52,54,56,58,60]
other (sanitation & hospitality): rates = [10,12,14,16,18,20,22,24,26,28,30]

The array of average hourly payrates for each year should be:

[10, 12, 24, 26, 38, 50, 52, 54]

My current best effort is not successful at producing the above array. Instead I get:

[12, 12, 24, 24, 36, 48, 48, 24]

The last element is 24 because the employee did work a full 12 months before retiring. I'm not concerned about that particular element. I'm energized about figuring out why the other elements are incorrect.

The below code can be pasted into Playground:

extension Array {
    func chunked(into size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[$0 ..< Swift.min($0 + size, count)])
        }
    }
}
enum Department: RawRepresentable {
    case sales
    case management
    case seniorManagement
    case other(String)

    init?(rawValue: String) {
        switch rawValue {
        case "Sales": self = .sales
        case "Management": self = .management
        case "Senior Management": self = .seniorManagement
        case let dept: self = .other(dept)
        }
    }
    var rawValue: String {
        switch self {
        case .sales: return "Sales"
        case .management: return "Management"
        case .seniorManagement: return "Senior Management"
        case .other(let dept): return dept
        }
    }
    func payRate(forYearsWorked numberOfYears: Int) -> Double {
        let rates: [Double]
        switch self {
        case .sales: rates = [20,22,24,26,28,30,32,34,36,38,40]
        case .management: rates = [30,32,34,36,38,40,42,44,46,48,50]
        case .seniorManagement: rates = [40,42,44,46,48,50,52,54,56,58,60]
        default: rates = [10,12,14,16,18,20,22,24,26,28,30]
        }
        return rates[min(numberOfYears, rates.count) - 1]
    }
}
struct Employee: Identifiable, Equatable, Hashable {
    static func ==(lhs: Employee, rhs: Employee) -> Bool {
            return lhs.id == rhs.id
        }

        func hash(into hasher: inout Hasher) {
            hasher.combine(id)
        }
    var id = UUID()
    let name: String
    var birthdate: Date
    var hiredate: Date
    var retirementAge: Int
    var department: Department
    var monthlyHoursWorked: Double
    var planningToPromote1: Bool
    var planningToPromote2: Bool
    var planningToPromote3: Bool
    var planningToPromote4: Bool
    var promotion1Date: Date
    var promotion2Date: Date
    var promotion3Date: Date
    var promotion4Date: Date
    var secondDepartment: Department
    var thirdDepartment: Department
    var fourthDepartment: Department
    var fifthDepartment: Department
    var regularPayRateIncreases: Bool
    var regularPayRateIncreasePercentage: Int
    var regularPayRateIncreaseYearInterval: Int

    private(set) var employmentHistory: [Department]

    init(_ name: String,
         birthdate: Date,
         hiredate: Date,
         retirementAge: Int,
         department: Department = .other("Employee"),
         monthlyHoursWorked: Double,
         planningToPromote1: Bool,
         planningToPromote2: Bool,
         planningToPromote3: Bool,
         planningToPromote4: Bool,
         promotion1Date: Date,
         promotion2Date: Date,
         promotion3Date: Date,
         promotion4Date: Date,
         secondDepartment: Department = .other("Employee"),
         thirdDepartment: Department = .other("Employee"),
         fourthDepartment: Department = .other("Employee"),
         fifthDepartment: Department = .other("Employee"),
         regularPayRateIncreases: Bool,
         regularPayRateIncreasePercentage: Int,
         regularPayRateIncreaseYearInterval: Int)
    {
        self.name = name
        self.birthdate = birthdate
        self.hiredate = hiredate
        self.retirementAge = retirementAge
        self.department = department
        self.monthlyHoursWorked = monthlyHoursWorked
        self.planningToPromote1 = planningToPromote1
        self.planningToPromote2 = planningToPromote2
        self.planningToPromote3 = planningToPromote3
        self.planningToPromote4 = planningToPromote4
        self.promotion1Date = promotion1Date
        self.promotion2Date = promotion2Date
        self.promotion3Date = promotion3Date
        self.promotion4Date = promotion4Date
        self.secondDepartment = secondDepartment
        self.thirdDepartment = thirdDepartment
        self.fourthDepartment = fourthDepartment
        self.fifthDepartment = fifthDepartment
        self.regularPayRateIncreases = regularPayRateIncreases
        self.regularPayRateIncreasePercentage = regularPayRateIncreasePercentage
        self.regularPayRateIncreaseYearInterval = regularPayRateIncreaseYearInterval
        self.employmentHistory = []
    }
}
extension Employee {
    mutating func promote(to newDepartment: Department) {
        department = newDepartment
    }
    mutating func work(months: Int) {
        employmentHistory
            .append(contentsOf: Array.init(repeating: department,
                                           count: months))
    }
    mutating func work(years: Int) {
        work(months: years * 12)
    }
    mutating func work(years: Int, months: Int) {
        work(months: years * 12 + months)
    }
    func employmentHistoryPayRates() -> [Double] {
        let years = employmentHistory.chunked(into: 12)
        var historyOfPayRates: [Double] = []
        for (index, months) in years.enumerated() {
            let employmentHistoryPayRates: Double = months.reduce(0) {result, dept in
                let payRate = dept.payRate(forYearsWorked: index + 1
                )/12
                return Double(String(format: "%.0f", result + payRate)) ?? result + payRate
            }
            historyOfPayRates.append(employmentHistoryPayRates)
        }
        return historyOfPayRates
    }
}
extension Employee {
    func yearlyDepartments() -> [String] {
        let years = employmentHistory.chunked(into: 12)
        let departments: [String] = years.map { months in
            var seenDepts: Set<String> = []
            return months.reduce(into: [String]()) { acc, dept in
                if seenDepts.insert(dept.rawValue).inserted {
                    acc.append(dept.rawValue)
                }
            }.joined(separator: ",")
        }
        return departments
    }
    func yearlyDepartmentsRates() -> [(String, Double)] {
        let yearlyDepartments = yearlyDepartments()
        let yearlyRates = employmentHistoryPayRates()
        let yearlyDepartmentsRates: [(departments: String, rates: Double)] =
        Array(zip(yearlyDepartments, yearlyRates))
        return yearlyDepartmentsRates
    }
}
var birthdate = DateComponents(calendar: .current, year: 1965, month: 7, day: 20).date!
var hiredate = DateComponents(calendar: .current, year: 2022, month: 12, day: 28).date!
var promotion1date = DateComponents(calendar: .current, year: 2023, month: 12, day: 28).date!
var firstDeptMonths: Int { Calendar.current.dateComponents([.month], from: hiredate, to: promotion1date).month! }
var promotion2date = DateComponents(calendar: .current, year: 2024, month: 12, day: 28).date!
var secondDeptMonths: Int { Calendar.current.dateComponents([.month], from: promotion1date, to: promotion2date).month! }
var promotion3date = DateComponents(calendar: .current, year: 2026, month: 12, day: 28).date!
var thirdDeptMonths: Int { Calendar.current.dateComponents([.month], from: promotion2date, to: promotion3date).month! }
var promotion4date = DateComponents(calendar: .current, year: 2027, month: 12, day: 28).date!
var fourthDeptMonths: Int { Calendar.current.dateComponents([.month], from: promotion3date, to: promotion4date).month! }
var retireAge = 65
let retireDate = Calendar.current.date(byAdding: .year, value: retireAge, to: birthdate)!
var fifthDeptMonths: Int { Calendar.current.dateComponents([.month], from: promotion4date, to: retireDate).month! }

extension Date {
    var age: Int { Calendar.current.dateComponents([.year], from: self, to: Date()).year! }
    var yearGroup: Int { Calendar.current.dateComponents([.year], from: self, to: Date()).year! + 1 }
    var totalYearsRemaining: Int { Calendar.current.dateComponents([.year], from: self, to: retireDate).year! }
    var totalMonthsRemaining: Int { Calendar.current.dateComponents([.month], from: self, to: retireDate).month! }
}
//age of employee
let age = birthdate.age
//number of years employee has worked for the company
let yearGroup = hiredate.yearGroup

func printYearlyDepartments(_ yearlyDepts: [(String)]) {
    for (year, depts) in yearlyDepts.enumerated() {
        print("Years since hired: \(year + yearGroup + 1)")
        print("Department(s) for Year \(year + yearGroup + 1): \(depts)")
        print("Age: \(year + age)")
        print("")
    }
}
func printEmploymentHistoryRates(_ yearlyDeptsAndRates: [(departments: String, rates: Double)]) {
    for (year, deptsAndRates) in yearlyDeptsAndRates.enumerated() {
        print("Department(s) for Year \(year + yearGroup + 1): \(deptsAndRates.departments)")
        print("Payrate for Year \(year + yearGroup + 1): $\(deptsAndRates.rates)")
        print("")
    }
}

var charlotte = 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!,
                         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)

charlotte.work(months: firstDeptMonths)
charlotte.promote(to: .other("Hospitality"))
charlotte.work(months: secondDeptMonths)
charlotte.promote(to: .sales)
charlotte.work(months: thirdDeptMonths)
charlotte.promote(to: .management)
charlotte.work(months: fourthDeptMonths)
charlotte.promote(to: .seniorManagement)
charlotte.work(months: fifthDeptMonths)

charlotte.yearlyDepartmentsRates()
charlotte.employmentHistoryPayRates()

2      

Hi @comeandtakeit99, I made some changes to the employmentHistoryPayRates func and it gave me the correct results.

func employmentHistoryPayRates() -> [Double] {
        let years = employmentHistory.chunked(into: 12)
        var historyOfPayRates: [Double] = []
        for (index, months) in years.enumerated() {
            let employmentHistoryPayRates: Double = months.reduce(0) {result, dept in
                let payRate = dept.payRate(forYearsWorked: index + 1) // Removed the '/ 12'
                return Double(String(format: "%.0f", payRate)) ?? payRate // Removed the 'result + payRate'
            }
            historyOfPayRates.append(employmentHistoryPayRates)
        }
        return historyOfPayRates
    }

3      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

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.