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  }