How to do it...

The following steps cover how to write and run your application:

  1. From your Terminal/console application, create a new directory called ~/projects/go-programming-cookbook/chapter3/collections.
  2. Navigate to this directory.
  3. Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter3/collections

You should see a file called go.mod that contains the following:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter3/collections    
  1. Copy tests from ~/projects/go-programming-cookbook-original/chapter3/collections, or use this as an exercise to write some of your own code!
  1. Create a file called collections.go with the following content:
        package collections

// WorkWith is the struct we'll
// be implementing collections for
type WorkWith struct {
Data string
Version int
}

// Filter is a functional filter. It takes a list of
// WorkWith and a WorkWith Function that returns a bool
// for each "true" element we return it to the resultant
// list
func Filter(ws []WorkWith, f func(w WorkWith) bool) []WorkWith
{
// depending on results, smalles size for result
// is len == 0
result := make([]WorkWith, 0)
for _, w := range ws {
if f(w) {
result = append(result, w)
}
}
return result
}

// Map is a functional map. It takes a list of
// WorkWith and a WorkWith Function that takes a WorkWith
// and returns a modified WorkWith. The end result is
// a list of modified WorkWiths
func Map(ws []WorkWith, f func(w WorkWith) WorkWith) []WorkWith
{
// the result should always be the same
// length
result := make([]WorkWith, len(ws))

for pos, w := range ws {
newW := f(w)
result[pos] = newW
}
return result
}
  1. Create a file called functions.go with the following content:
        package collections

import "strings"

// LowerCaseData does a ToLower to the
// Data string of a WorkWith
func LowerCaseData(w WorkWith) WorkWith {
w.Data = strings.ToLower(w.Data)
return w
}

// IncrementVersion increments a WorkWiths
// Version
func IncrementVersion(w WorkWith) WorkWith {
w.Version++
return w
}

// OldVersion returns a closures
// that validates the version is greater than
// the specified amount
func OldVersion(v int) func(w WorkWith) bool {
return func(w WorkWith) bool {
return w.Version >= v
}
}
  1. Create a new directory named example and navigate to it.
  2. Create a file called main.go with the following content:
        package main

import (
"fmt"

"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter3/collections"
)

func main() {
ws := []collections.WorkWith{
collections.WorkWith{"Example", 1},
collections.WorkWith{"Example 2", 2},
}

fmt.Printf("Initial list: %#v\n", ws)

// first lower case the list
ws = collections.Map(ws, collections.LowerCaseData)
fmt.Printf("After LowerCaseData Map: %#v\n", ws)

// next increment all versions
ws = collections.Map(ws, collections.IncrementVersion)
fmt.Printf("After IncrementVersion Map: %#v\n", ws)

// lastly remove all versions older than 3
ws = collections.Filter(ws, collections.OldVersion(3))
fmt.Printf("After OldVersion Filter: %#v\n", ws)
}
  1. Run go run main.go. You could also run the following:
$ go build
$ ./example

You should see the following output:

$ go run main.go
Initial list:
[]collections.WorkWith{collections.WorkWith{Data:"Example",
Version:1}, collections.WorkWith{Data:"Example 2", Version:2}}

After LowerCaseData Map:
[]collections.WorkWith{collections.WorkWith{Data:"example",
Version:1}, collections.WorkWith{Data:"example 2", Version:2}}

After IncrementVersion Map:
[]collections.WorkWith{collections.WorkWith{Data:"example",
Version:2}, collections.WorkWith{Data:"example 2", Version:3}}

After OldVersion Filter:
[]collections.WorkWith{collections.WorkWith{Data:"example 2",
Version:3}}
  1. If you copied or wrote your own tests, go up one directory and run go test. Ensure that all tests pass.