Skip to content

Instantly share code, notes, and snippets.

@jonbodner
Created June 6, 2012 21:43
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 jonbodner/2885023 to your computer and use it in GitHub Desktop.
Save jonbodner/2885023 to your computer and use it in GitHub Desktop.
Trivial map/reduce in Go
package main
import "fmt"
type FSlice []interface{}
type Collector func(interface{}) interface{}
type Reducer func(*interface{}, interface{})
type Filter func(interface{}) bool
func (fs FSlice) Collect(f Collector) FSlice {
out := make(FSlice, len(fs))
for k, v := range fs {
out[k] = f(v)
}
return out
}
func (fs FSlice) Find(f Filter) interface{} {
for _, v := range fs {
if f(v) {
return v
}
}
return nil
}
func (fs FSlice) FindAll(f Filter) FSlice {
out := make(FSlice, 0)
for _, v := range fs {
if f(v) {
out = append(out, v)
}
}
return out
}
func (fs FSlice) Inject(f Reducer, initial interface{}) interface{} {
for _, v := range fs {
f(&initial, v)
}
return initial
}
func (fs *FSlice) RetainAll(f Filter) {
*fs = fs.FindAll(f)
}
func (fs *FSlice) RemoveAll(f Filter) {
fs.RetainAll(Not(f))
}
func (fs FSlice) GroupBy(f Collector) map[interface{}][]interface{} {
out := make(map[interface{}][]interface{})
for _, v := range fs {
key := f(v)
value, ok := out[key]
if ok {
value = append(value, v)
} else {
value = make([]interface{}, 1)
value[0] = v
}
out[key] = value
}
return out
}
func (fs FSlice) Split(f Filter) (match, notMatch []interface{}) {
match = make(FSlice, 0)
notMatch = make(FSlice, 0)
for _, v := range fs {
if f(v) {
match = append(match, v)
} else {
notMatch = append(notMatch, v)
}
}
return
}
func Not(f Filter) Filter {
return func(v interface{}) bool {
return !f(v)
}
}
func sum(running *interface{}, v interface{}) {
*running = v.(int) + (*running).(int)
}
func mult(running *interface{}, v interface{}) {
*running = v.(int) * (*running).(int)
}
func double(x interface{}) interface{} {
return x.(int) * 2
}
func even(x interface{}) bool {
return x.(int)%2 == 0
}
func mod(x interface{}) interface{} {
return x.(int) % 2
}
func main() {
x := FSlice{1, 2, 3, 4}
t := x.Collect(double)
s := x.Inject(sum, 0)
m := x.Inject(mult, 1)
f := x.FindAll(even)
f1 := x.Find(even)
multiple := x.FindAll(even).Collect(double).Inject(sum, 0)
fmt.Println(x)
fmt.Println(t)
fmt.Println(f)
fmt.Println(f1)
fmt.Println(s)
fmt.Println(m)
fmt.Println(multiple)
fmt.Println(x.GroupBy(mod))
fmt.Println(x.Split(even))
x.RemoveAll(even)
fmt.Println(x)
}
@jonbodner
Copy link
Author

Executable version at http://play.golang.org/p/OCDth4TOfg

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