github.com/l3x/learn-fp-go@v0.0.0-20171228022418-7639825d0b71/1-functional-fundamentals/ch03-hof/03_hof/src/hof/cars.go (about) 1 package hof 2 3 import ( 4 "fmt" 5 s "strings" 6 "regexp" 7 "log" 8 "encoding/json" 9 ) 10 11 var CarsDB = initCarsDB() 12 13 func initCarsDB() []IndexedCar { 14 var indexedCars []IndexedCar 15 for i, car := range LoadCars() { 16 indexedCars = append(indexedCars, IndexedCar{i, car}) 17 } 18 lenCars := len(indexedCars) 19 for i, car := range LoadMoreCars() { 20 indexedCars = append(indexedCars, IndexedCar{i + lenCars, car}) 21 } 22 return indexedCars 23 } 24 25 func LoadCars() Collection { 26 return CsvToStruct("cars.csv") 27 } 28 29 func LoadMoreCars() Collection { 30 return CsvToStruct("more_cars.csv") 31 } 32 33 34 func (cars Collection) AddCars(carsToAdd Collection) Collection { 35 return append(cars, carsToAdd...) 36 } 37 38 39 // Reduce collection based on the function 40 func (cars Collection) Reduce(fn ReducerFunc, accumulator Collection) Collection { 41 var result = accumulator 42 for _, car := range cars { 43 result = append(fn(car, result)) 44 } 45 return result 46 } 47 func (cars Collection) Reduce2(fn ReducerFunc2, accumulator CarCollection) CarCollection { 48 var result = accumulator 49 for _, car := range cars { 50 result = append(fn(car, result)) 51 } 52 return result 53 } 54 55 func JsonReducer(cars Collection) ReducerFunc { 56 return func(car string, cars Collection) Collection { 57 JSON := fmt.Sprintf("{\"car\": {\"make\": \"%s\", \"model\": \"%s\"}}", GetMake(car), GetModel(car)) 58 cars = append(cars, JSON) 59 return cars 60 } 61 } 62 63 func CarTypeReducer(cars Collection) ReducerFunc2 { 64 65 return func(car string, cars CarCollection) CarCollection { 66 JSON := fmt.Sprintf("{\"make\": \"%s\", \"model\": \"%s\"}", GetMake(car), GetModel(car)) 67 var c CarType 68 err := json.Unmarshal([]byte(JSON), &c) 69 if err != nil { 70 log.Fatal("ERROR:", err) 71 } 72 cars = append(cars, c) 73 return cars 74 } 75 } 76 77 func MakeReducer(make string, cars Collection) ReducerFunc { 78 return func(car string, cars Collection) Collection { 79 if s.Contains(car, make) { 80 cars = append(cars, car) 81 } 82 return cars 83 } 84 } 85 86 func (cars Collection) Filter(fn FilterFunc) Collection { 87 filteredCars := make(Collection, 0) 88 for _, car := range cars { 89 if fn(car) { 90 filteredCars = append(filteredCars, car) 91 } 92 } 93 return filteredCars 94 } 95 96 func ByMake(make string) FilterFunc { 97 return func(car string) bool { 98 return s.Contains(car, make) 99 } 100 } 101 102 func ByForeign() FilterFunc { 103 return func(car string) bool { 104 return !isDomestic(car) 105 } 106 } 107 108 func isDomestic(car string) bool { 109 return s.Contains(car, "Ford") || s.Contains(car, "GM") || s.Contains(car, "Chrysler") 110 } 111 112 func ByDomestic() FilterFunc { 113 return func(car string) bool { 114 return isDomestic(car) 115 } 116 } 117 118 func ByHasNumber() FilterFunc { 119 return func(car string) bool { 120 match, _ := regexp.MatchString(".+[0-9].*", car) 121 return match 122 } 123 } 124 125 func ByModel(model string) FilterFunc { 126 return func(car string) bool { 127 return s.Contains(car, model) 128 } 129 } 130 131 func (cars Collection) Map(fn MapFunc) Collection { 132 mappedCars := make(Collection, 0, len(cars)) 133 for _, car := range cars { 134 mappedCars = append(mappedCars, fn(car)) 135 } 136 return mappedCars 137 } 138 139 func Upgrade() MapFunc { 140 return func(car string) string { 141 return fmt.Sprintf("%s %s", car, UpgradeLabel(car)) 142 } 143 } 144 145 func Downgrade() MapFunc { 146 return func(car string) string { 147 return car[:len(car)-2] 148 } 149 } 150 151 func UpgradeLabel(car string) string { 152 return map[string]string{ 153 "Honda": "LX", 154 "Lexus": "LS", 155 "Toyota": "EV", 156 "Ford": "XL", 157 "GM": "X", 158 }[GetMake(car)] 159 } 160 161 func (cars Collection) String() string { 162 return s.Join(cars, ",") 163 } 164 165 166 func x() { 167 val, err := buggyCode() 168 // more code 169 return 170 171 }