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

 Mar '23 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 = [] 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()`````` Mar '23 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 }`````` 1

SPONSORED An iOS conference hosted in Buenos Aires, Argentina – join us for the third edition from November 29th to December 1st!

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