Skip to content

Instantly share code, notes, and snippets.

@caelifer
Last active October 14, 2016 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caelifer/641aa9c54c823a7c43a775beac12a4bf to your computer and use it in GitHub Desktop.
Save caelifer/641aa9c54c823a7c43a775beac12a4bf to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"strings"
)
func main() {
strs := StringSlice{"Hello", "foo", "bar"}
ints := IntSlice{1, 2, 3, 4}
// Example use Map with custom and stdlib functions
excl := func(s string) string { return s + "!" }
fmt.Println(strs, "->", strs.Map(excl))
fmt.Println(strs, "->", strs.Map(strings.Title))
// Example using Map->Grep chain
hasOh := func(s string) bool { return strings.ContainsAny(s, "Oo") }
fmt.Println(strs, "->", strs.Map(strings.ToLower).Grep(hasOh))
// Same examples for ints
double := func(i int) int { return i * 2 }
fmt.Println(ints, "->", ints.Map(double))
tripple := func(i int) int { return i * 3 }
even := func(i int) bool { return i&0x1 == 0 }
fmt.Println(ints, "->", ints.Map(tripple).Grep(even))
// Type mismatch eror case
fmt.Println(ints, "->", ints.Map(tripple).Grep(even).Grep(hasOh))
}
////////////////////////////////
//// -- Type definitions -- ////
////////////////////////////////
type Mapper interface {
Map(transformer interface{}) Functional
}
type Grepper interface {
Grep(predicate interface{}) Functional
}
type Functional interface {
Mapper
Grepper
}
type StringSlice []string
func (slice StringSlice) Map(f interface{}) Functional {
res := StringSlice(make([]string, 0, len(slice)))
fn := f.(func(string) string)
for _, v := range slice {
res = append(res, fn(v))
}
return res
}
func (slice StringSlice) Grep(p interface{}) Functional {
res := StringSlice(make([]string, 0, len(slice)))
fn := p.(func(string) bool)
for _, v := range slice {
if fn(v) {
res = append(res, v)
}
}
return res
}
type IntSlice []int
func (slice IntSlice) Map(f interface{}) Functional {
res := IntSlice(make([]int, 0, len(slice)))
fn := f.(func(int) int)
for _, v := range slice {
res = append(res, fn(v))
}
return res
}
func (slice IntSlice) Grep(p interface{}) Functional {
res := IntSlice(make([]int, 0, len(slice)))
fn := p.(func(int) bool)
for _, v := range slice {
if fn(v) {
res = append(res, v)
}
}
return res
}
@caelifer
Copy link
Author

caelifer commented Oct 14, 2016

Live example - https://play.golang.org/p/AR1u7EXkno
Output:

[Hello foo bar] -> [Hello! foo! bar!]
[Hello foo bar] -> [Hello Foo Bar]
[Hello foo bar] -> [hello foo]
[1 2 3 4] -> [2 4 6 8]
[1 2 3 4] -> [6 12]
panic: interface conversion: interface {} is func(string) bool, not func(int) bool

goroutine 1 [running]:
panic(0x104da0, 0x10432360)
    /usr/local/go/src/runtime/panic.go:500 +0x720
main.IntSlice.Grep(0x1040e2d0, 0x2, 0x4, 0x100ca0, 0x139664, 0x1040e130, 0x0, 0x0)
    /tmp/sandbox693237750/main.go:86 +0x260
main.(*IntSlice).Grep(0x1040e2e0, 0x100ca0, 0x139664, 0x100aa0, 0x0, 0x0)
    <autogenerated>:6 +0xe0
main.main()
    /tmp/sandbox693237750/main.go:31 +0xbe0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment