246 lines
7.7 KiB
Go
246 lines
7.7 KiB
Go
package proto
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"reflect"
|
|
)
|
|
|
|
func GetMax[T float64 | float32 | int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64](a, b T) T {
|
|
if a > b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|
|
|
|
func GetMin[T float64 | float32 | int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64](a, b T) T {
|
|
if a < b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|
|
|
|
|
|
type EmployeeField string
|
|
|
|
const (
|
|
FieldEmpID EmployeeField = "EmpId"
|
|
FieldNamePrefix = "NamePrefix"
|
|
FieldFirstName = "FirstName"
|
|
FieldMiddleInitial = "MiddleInitial"
|
|
FieldLastName = "LastName"
|
|
FieldGender = "Gender"
|
|
FieldEmail = "Email"
|
|
FieldFathersName = "FathersName"
|
|
FieldMothersName = "MothersName"
|
|
FieldMothersMaidenName = "MothersMaidenName"
|
|
FieldBirthdate = "Birthdate"
|
|
FieldBirthTime = "BirthTime"
|
|
FieldWeightKg = "WeightKg"
|
|
FieldJoiningDate = "JoiningDate"
|
|
FieldJoiningQuarter = "JoiningQuarter"
|
|
FieldJoiningHalf = "JoiningHalf"
|
|
FieldJoiningYear = "JoiningYear"
|
|
FieldJoiningMonth = "JoiningMonth"
|
|
FieldJoiningMonthName = "JoiningMonthName"
|
|
FieldJoiningMonthNameShort = "JoiningMonthNameShort"
|
|
FieldJoiningMonthDay = "JoiningMonthDay"
|
|
FieldJoiningWeekDay = "JoiningWeekDay"
|
|
FieldJoiningWeekDayShort = "JoiningWeekDayShort"
|
|
FieldYearsOfService = "YearsOfService"
|
|
FieldSalary = "Salary"
|
|
FieldLatestHikePercentage = "LatestHikePercentage"
|
|
FieldSsn = "Ssn"
|
|
FieldPhoneNumber = "PhoneNumber"
|
|
FieldPlaceName = "PlaceName"
|
|
FieldCounty = "County"
|
|
FieldCity = "City"
|
|
FieldState = "State"
|
|
FieldZip = "Zip"
|
|
FieldRegion = "Region"
|
|
FieldUsername = "Username"
|
|
FieldPassword = "Password"
|
|
)
|
|
|
|
func (e *Employee) Copy() Employee {
|
|
return Employee{
|
|
EmpId: e.GetEmpId(),
|
|
NamePrefix: e.GetNamePrefix(),
|
|
FirstName: e.GetFirstName(),
|
|
MiddleInitial: e.GetMiddleInitial(),
|
|
LastName: e.GetLastName(),
|
|
Gender: e.GetGender(),
|
|
Email: e.GetEmail(),
|
|
FathersName: e.GetFathersName(),
|
|
MothersName: e.GetMothersName(),
|
|
MothersMaidenName: e.GetMothersMaidenName(),
|
|
Birthdate: e.GetBirthdate(),
|
|
BirthTime: e.GetBirthTime(),
|
|
WeightKg: e.GetWeightKg(),
|
|
JoiningDate: e.GetJoiningDate(),
|
|
JoiningQuarter: e.GetJoiningQuarter(),
|
|
JoiningHalf: e.GetJoiningHalf(),
|
|
JoiningYear: e.GetJoiningYear(),
|
|
JoiningMonth: e.GetJoiningMonth(),
|
|
JoiningMonthName: e.GetJoiningMonthName(),
|
|
JoiningMonthNameShort: e.GetJoiningMonthNameShort(),
|
|
JoiningMonthDay: e.GetJoiningMonthDay(),
|
|
JoiningWeekDay: e.GetJoiningWeekDay(),
|
|
JoiningWeekDayShort: e.GetJoiningWeekDayShort(),
|
|
YearsOfService: e.GetYearsOfService(),
|
|
Salary: e.GetSalary(),
|
|
LatestHikePercentage: e.GetLatestHikePercentage(),
|
|
Ssn: e.GetSsn(),
|
|
PhoneNumber: e.GetPhoneNumber(),
|
|
PlaceName: e.GetPlaceName(),
|
|
County: e.GetCounty(),
|
|
City: e.GetCity(),
|
|
State: e.GetState(),
|
|
Zip: e.GetZip(),
|
|
Region: e.GetRegion(),
|
|
Username: e.GetUsername(),
|
|
Password: e.GetPassword(),
|
|
}
|
|
}
|
|
|
|
func (el *EmployeeList) QueryEmployeesByColumn(column EmployeeField, query string) ([]*Employee, error) {
|
|
employees := make([]*Employee, 0)
|
|
|
|
for _, employee := range el.GetEmployees() {
|
|
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
|
if fmt.Sprintf("%v", value) == query {
|
|
employees = append(employees, employee)
|
|
}
|
|
}
|
|
|
|
return employees, nil
|
|
}
|
|
|
|
type Groups map[string][]*Employee
|
|
|
|
func (el *EmployeeList) GroupByColumn(column EmployeeField) Groups {
|
|
|
|
groups := make(map[string][]*Employee)
|
|
for _, employee := range el.GetEmployees() {
|
|
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
|
formattedValue := fmt.Sprintf("%v", value)
|
|
groups[formattedValue] = append(groups[formattedValue], employee)
|
|
}
|
|
|
|
return groups
|
|
}
|
|
|
|
type FilterFunction func(*Employee) bool
|
|
|
|
func (grps Groups) HavingByColumn(cb FilterFunction) Groups {
|
|
|
|
newGrps := make(map[string][]*Employee)
|
|
|
|
for groupName, group := range grps {
|
|
for _, employee := range group {
|
|
if cb(employee) {
|
|
newGrps[groupName] = append(newGrps[groupName], employee)
|
|
}
|
|
}
|
|
}
|
|
|
|
return newGrps
|
|
}
|
|
|
|
func ForEachGroup[T any](grps Groups, cb func(ep EmployeePList) T) map[string]T {
|
|
g := make(map[string]T)
|
|
for groupName, group := range grps {
|
|
g[groupName] = cb(group)
|
|
}
|
|
|
|
return g
|
|
}
|
|
|
|
func AggregateByColumn[T any](el *EmployeeList, column EmployeeField, cb func(ep EmployeePList) T) map[string]T {
|
|
|
|
grps := el.GroupByColumn(column)
|
|
res := ForEachGroup(grps, cb)
|
|
|
|
return res
|
|
}
|
|
|
|
type EmployeePList []*Employee
|
|
|
|
func Sum(ep EmployeePList, column EmployeeField) float64 {
|
|
sum := 0.0
|
|
|
|
_, fieldFound := reflect.TypeOf(Employee{}).FieldByName(string(column))
|
|
if !fieldFound {
|
|
return sum
|
|
}
|
|
|
|
for _, employee := range ep {
|
|
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
|
switch value.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
sum += float64(value.Int())
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
sum += float64(value.Uint())
|
|
case reflect.Float64, reflect.Float32:
|
|
sum += value.Float()
|
|
default:
|
|
return sum
|
|
}
|
|
}
|
|
return sum
|
|
}
|
|
|
|
func Average(ep EmployeePList, column EmployeeField) float64 {
|
|
return Sum(ep, column) / float64(len(ep))
|
|
}
|
|
|
|
func Max(ep EmployeePList, column EmployeeField) float64 {
|
|
max := 0.0
|
|
|
|
_, fieldFound := reflect.TypeOf(Employee{}).FieldByName(string(column))
|
|
if !fieldFound {
|
|
return max
|
|
}
|
|
|
|
for _, employee := range ep {
|
|
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
|
switch value.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
max = GetMax(max, float64(value.Int()))
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
max = GetMax(max, float64(value.Uint()))
|
|
case reflect.Float64, reflect.Float32:
|
|
max = GetMax(max, value.Float())
|
|
default:
|
|
return max
|
|
}
|
|
}
|
|
|
|
return max
|
|
}
|
|
|
|
func Min(ep EmployeePList, column EmployeeField) float64 {
|
|
min := math.MaxFloat64
|
|
|
|
_, fieldFound := reflect.TypeOf(Employee{}).FieldByName(string(column))
|
|
if !fieldFound {
|
|
return min
|
|
}
|
|
|
|
for _, employee := range ep {
|
|
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
|
switch value.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
min = GetMin(min, float64(value.Int()))
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
min = GetMin(min, float64(value.Uint()))
|
|
case reflect.Float64, reflect.Float32:
|
|
min = GetMin(min, value.Float())
|
|
default:
|
|
return min
|
|
}
|
|
}
|
|
|
|
return min
|
|
}
|