github.com/l3x/learn-fp-go@v0.0.0-20171228022418-7639825d0b71/1-functional-fundamentals/ch02-collections/02_chainlink/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 const ( 9 ZERO WordSize = 6 * iota 10 SMALL 11 MEDIUM 12 LARGE 13 XLARGE 14 XXLARGE WordSize = 50 15 SEPARATOR = ", " 16 ) 17 18 type WordSize int 19 20 type ChainLink struct { 21 Data []string 22 } 23 24 func (v *ChainLink) Value() []string { 25 return v.Data 26 } 27 28 // stringFunc is a first-class method, used as a parameter to Map 29 type stringFunc func(s string) (result string) 30 31 // Map uses stringFunc to modify (up-case) each string in the slice 32 func (v *ChainLink) Map(fn stringFunc) *ChainLink { 33 var mapped []string 34 orig := *v 35 for _, s := range orig.Data { 36 mapped = append(mapped, fn(s)) // first-class function 37 } 38 v.Data = mapped 39 return v 40 } 41 42 // Filter uses embedded logic to filter the slice of strings 43 // Note: We could have chosen to use a first-class function 44 func (v *ChainLink) Filter(max WordSize) *ChainLink { 45 filtered := []string{} 46 orig := *v 47 for _, s := range orig.Data { 48 if len(s) <= int(max) { // embedded logic 49 filtered = append(filtered, s) 50 } 51 } 52 v.Data = filtered 53 return v 54 } 55 56 57 func main() { 58 constants := ` 59 ** Constants *** 60 ZERO: %v 61 SMALL: %d 62 MEDIUM: %d 63 LARGE: %d 64 XLARGE: %d 65 XXLARGE: %d 66 ` 67 fmt.Printf(constants, ZERO, SMALL, MEDIUM, LARGE, XLARGE, XXLARGE) 68 69 words := []string{ 70 "tiny", 71 "marathon", 72 "philanthropinist", 73 "supercalifragilisticexpialidocious"} 74 75 data := ChainLink{words}; 76 fmt.Printf("unfiltered: %#v\n", data.Value()) 77 78 filtered := data.Filter(SMALL) 79 fmt.Printf("filtered: %#v\n", filtered) 80 81 fmt.Printf("filtered and mapped (<= SMALL sized words): %#v\n", 82 filtered.Map(strings.ToUpper).Value()) 83 84 data = ChainLink{words} 85 fmt.Printf("filtered and mapped (<= Up to MEDIUM sized words): %#v\n", 86 data.Filter(MEDIUM).Map(strings.ToUpper).Value()) 87 88 data = ChainLink{words} 89 fmt.Printf("filtered twice and mapped (<= Up to LARGE sized words): %#v\n", 90 data.Filter(XLARGE).Map(strings.ToUpper).Filter(LARGE).Value()) 91 92 data = ChainLink{words} 93 val := data.Map(strings.ToUpper).Filter(XXLARGE).Value() 94 fmt.Printf("mapped and filtered (<= Up to XXLARGE sized words): %#v\n", val) 95 }