|  | 
|  | 1 | +package main | 
|  | 2 | + | 
|  | 3 | +import ( | 
|  | 4 | +	"fmt" | 
|  | 5 | +	"slices" | 
|  | 6 | +	"sort" | 
|  | 7 | +	"strings" | 
|  | 8 | +	"time" | 
|  | 9 | +) | 
|  | 10 | + | 
|  | 11 | +/* -------------------------------------------------------------------------- */ | 
|  | 12 | +/*                                    TYPES                                   */ | 
|  | 13 | +/* -------------------------------------------------------------------------- */ | 
|  | 14 | + | 
|  | 15 | +/* --------------------------------- Student -------------------------------- */ | 
|  | 16 | + | 
|  | 17 | +type Student struct { | 
|  | 18 | +	bornDate       time.Time | 
|  | 19 | +	name           string | 
|  | 20 | +	qualifications []float32 | 
|  | 21 | +} | 
|  | 22 | + | 
|  | 23 | +type Students []Student | 
|  | 24 | + | 
|  | 25 | +func (students Students) Print() { | 
|  | 26 | +	for _, student := range students { | 
|  | 27 | +		var studentBornDate string = fmt.Sprintf( | 
|  | 28 | +			"%02d-%02d-%4d", | 
|  | 29 | +			student.bornDate.Month(), | 
|  | 30 | +			student.bornDate.Day(), | 
|  | 31 | +			student.bornDate.Year(), | 
|  | 32 | +		) | 
|  | 33 | + | 
|  | 34 | +		fmt.Printf("\n%s / %s / %.2f", student.name, studentBornDate, student.qualifications) | 
|  | 35 | +	} | 
|  | 36 | +} | 
|  | 37 | + | 
|  | 38 | +type SortByYoungestBornDate Students | 
|  | 39 | + | 
|  | 40 | +func (students SortByYoungestBornDate) Len() int { return len(students) } | 
|  | 41 | +func (students SortByYoungestBornDate) Swap(i, j int) { | 
|  | 42 | +	students[i], students[j] = students[j], students[i] | 
|  | 43 | +} | 
|  | 44 | +func (students SortByYoungestBornDate) Less(i, j int) bool { | 
|  | 45 | +	return students[i].bornDate.After(students[j].bornDate) | 
|  | 46 | +} | 
|  | 47 | + | 
|  | 48 | +/* -------------------------------------------------------------------------- */ | 
|  | 49 | +/*                                  FUNCTIONS                                 */ | 
|  | 50 | +/* -------------------------------------------------------------------------- */ | 
|  | 51 | + | 
|  | 52 | +func Average(numbers ...float32) float32 { | 
|  | 53 | +	var total float32 | 
|  | 54 | + | 
|  | 55 | +	for _, number := range numbers { | 
|  | 56 | +		total += number | 
|  | 57 | +	} | 
|  | 58 | + | 
|  | 59 | +	return total / float32(len(numbers)) | 
|  | 60 | +} | 
|  | 61 | + | 
|  | 62 | +func ToFiltered[T any](slice []T, filterFn func(element T) bool) []T { | 
|  | 63 | +	var filteredSlice []T | 
|  | 64 | + | 
|  | 65 | +	for _, element := range slice { | 
|  | 66 | +		if filterFn(element) { | 
|  | 67 | +			filteredSlice = append(filteredSlice, element) | 
|  | 68 | +		} | 
|  | 69 | +	} | 
|  | 70 | + | 
|  | 71 | +	return filteredSlice | 
|  | 72 | +} | 
|  | 73 | + | 
|  | 74 | +func ToMap[T any](array []T, callback func(element T, index int) T) []T { | 
|  | 75 | +	var arrayCopy []T | 
|  | 76 | + | 
|  | 77 | +	for index, element := range array { | 
|  | 78 | +		var mappedElement T = callback(element, index) | 
|  | 79 | +		arrayCopy = append(arrayCopy, mappedElement) | 
|  | 80 | +	} | 
|  | 81 | + | 
|  | 82 | +	return arrayCopy | 
|  | 83 | +} | 
|  | 84 | + | 
|  | 85 | +/* -------------------------------------------------------------------------- */ | 
|  | 86 | +/*                                    MAIN                                    */ | 
|  | 87 | +/* -------------------------------------------------------------------------- */ | 
|  | 88 | + | 
|  | 89 | +func main() { | 
|  | 90 | +	/* | 
|  | 91 | +		Higher order functions (HOF)... | 
|  | 92 | +	*/ | 
|  | 93 | + | 
|  | 94 | +	fmt.Println("Higher order functions (HOF)...") | 
|  | 95 | + | 
|  | 96 | +	var names []string = []string{ | 
|  | 97 | +		"john", | 
|  | 98 | +		"mary", | 
|  | 99 | +		"david", | 
|  | 100 | +		"sarah", | 
|  | 101 | +		"james", | 
|  | 102 | +	} | 
|  | 103 | +	fmt.Printf("\nnames=%#v\n", names) | 
|  | 104 | + | 
|  | 105 | +	var capitalizedNames []string = ToMap(names, func(name string, index int) string { | 
|  | 106 | +		name = strings.TrimSpace(name) | 
|  | 107 | +		return strings.ToUpper(string(name[0])) + name[1:] | 
|  | 108 | +	}) | 
|  | 109 | +	fmt.Printf("\ncapitalizedNames=%#v\n", capitalizedNames) | 
|  | 110 | + | 
|  | 111 | +	var uppercasedNames []string = ToMap(names, func(name string, index int) string { | 
|  | 112 | +		name = strings.TrimSpace(name) | 
|  | 113 | +		return strings.ToUpper(name) | 
|  | 114 | +	}) | 
|  | 115 | + | 
|  | 116 | +	fmt.Printf("\nuppercasedNames=%#v\n", uppercasedNames) | 
|  | 117 | + | 
|  | 118 | +	fmt.Println("\n# ---------------------------------------------------------------------------------- #") | 
|  | 119 | + | 
|  | 120 | +	/* | 
|  | 121 | +		Additional challenge... | 
|  | 122 | +	*/ | 
|  | 123 | + | 
|  | 124 | +	fmt.Println("\nAdditional challenge...") | 
|  | 125 | + | 
|  | 126 | +	var students Students = []Student{ | 
|  | 127 | +		{ | 
|  | 128 | +			bornDate:       time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), | 
|  | 129 | +			name:           "Alice", | 
|  | 130 | +			qualifications: []float32{8.5, 9.0, 7.8}, | 
|  | 131 | +		}, | 
|  | 132 | +		{ | 
|  | 133 | +			bornDate:       time.Date(1999, time.February, 15, 0, 0, 0, 0, time.UTC), | 
|  | 134 | +			name:           "Bob", | 
|  | 135 | +			qualifications: []float32{7.2, 6.8, 8.0}, | 
|  | 136 | +		}, | 
|  | 137 | +		{ | 
|  | 138 | +			bornDate:       time.Date(2001, time.January, 10, 0, 0, 0, 0, time.UTC), | 
|  | 139 | +			name:           "Charlie", | 
|  | 140 | +			qualifications: []float32{9.5, 8.7, 9.2}, | 
|  | 141 | +		}, | 
|  | 142 | +		{ | 
|  | 143 | +			bornDate:       time.Date(2002, time.February, 5, 0, 0, 0, 0, time.UTC), | 
|  | 144 | +			name:           "David", | 
|  | 145 | +			qualifications: []float32{6.5, 7.0, 7.8}, | 
|  | 146 | +		}, | 
|  | 147 | +		{ | 
|  | 148 | +			bornDate:       time.Date(2000, time.May, 20, 0, 0, 0, 0, time.UTC), | 
|  | 149 | +			name:           "Eve", | 
|  | 150 | +			qualifications: []float32{8.0, 8.5, 7.2}, | 
|  | 151 | +		}, | 
|  | 152 | +		{ | 
|  | 153 | +			bornDate:       time.Date(1999, time.June, 25, 0, 0, 0, 0, time.UTC), | 
|  | 154 | +			name:           "Frank", | 
|  | 155 | +			qualifications: []float32{7.8, 7.5, 8.2}, | 
|  | 156 | +		}, | 
|  | 157 | +		{ | 
|  | 158 | +			bornDate:       time.Date(2001, time.February, 15, 0, 0, 0, 0, time.UTC), | 
|  | 159 | +			name:           "Grace", | 
|  | 160 | +			qualifications: []float32{9.0, 9.2, 8.7}, | 
|  | 161 | +		}, | 
|  | 162 | +		{ | 
|  | 163 | +			bornDate:       time.Date(2002, time.December, 10, 0, 0, 0, 0, time.UTC), | 
|  | 164 | +			name:           "Henry", | 
|  | 165 | +			qualifications: []float32{9.4, 7.87, 10.00}, | 
|  | 166 | +		}, | 
|  | 167 | +	} | 
|  | 168 | + | 
|  | 169 | +	fmt.Println("\nStudents...") | 
|  | 170 | +	students.Print() | 
|  | 171 | + | 
|  | 172 | +	fmt.Println("\n\nStudents with name and average qualification...") | 
|  | 173 | +	for _, student := range students { | 
|  | 174 | +		var averageQualification float32 = Average(student.qualifications...) | 
|  | 175 | +		fmt.Printf("\n%s / %.2f", student.name, averageQualification) | 
|  | 176 | +	} | 
|  | 177 | + | 
|  | 178 | +	var studentsWithAverageQualificationMoreThanNine Students = ToFiltered(students, func(student Student) bool { | 
|  | 179 | +		return Average(student.qualifications...) >= 9 | 
|  | 180 | +	}) | 
|  | 181 | + | 
|  | 182 | +	fmt.Println("\n\nStudents with an average qualification more than nine...") | 
|  | 183 | +	studentsWithAverageQualificationMoreThanNine.Print() | 
|  | 184 | + | 
|  | 185 | +	var sortedStudentsByBornDate Students = slices.Clone(students) | 
|  | 186 | +	sort.Sort(SortByYoungestBornDate(sortedStudentsByBornDate)) | 
|  | 187 | + | 
|  | 188 | +	fmt.Println("\n\nSorted students by born date (youngest to oldest)...") | 
|  | 189 | +	sortedStudentsByBornDate.Print() | 
|  | 190 | + | 
|  | 191 | +	fmt.Println("\n\nStudents with name and best qualification...") | 
|  | 192 | +	for _, student := range students { | 
|  | 193 | +		var bestQualification float32 = slices.Max(student.qualifications) | 
|  | 194 | +		fmt.Printf("\n%s / %.2f", student.name, bestQualification) | 
|  | 195 | +	} | 
|  | 196 | +} | 
0 commit comments