Skip to content

Instantly share code, notes, and snippets.

@3d0c
Created January 15, 2014 13:08
Show Gist options
  • Save 3d0c/8435889 to your computer and use it in GitHub Desktop.
Save 3d0c/8435889 to your computer and use it in GitHub Desktop.
func main() {
s := []string{"this", "is", "a", "test"}
mapper := func(s string) string {
return "prefix-" + s
}
tap := func(s string) {
fmt.Printf("tap: %s\n", s)
}
filter := func(s string) bool {
return len(s) >= 9
}
reducer := func(acc map[string]int, s string) map[string]int {
acc[s] = len(s)
return acc
}
m := Wrap(s).
Map(strings.ToUpper).
Map(mapper).
Tap(tap).
Filter(filter).
Reduce(reducer, map[string]int{}).
Val()
fmt.Println(m)
}
package main
import (
"fmt"
"reflect"
"strings"
)
func Filter(in interface{}, fn interface{}) interface{} {
var (
inType = reflect.TypeOf(in)
inValue = reflect.ValueOf(in)
inValueLen = inValue.Len()
fnValue = reflect.ValueOf(fn)
outValue = reflect.MakeSlice(inType, 0, 1)
)
for i := 0; i < inValueLen; i++ {
x := inValue.Index(i)
args := []reflect.Value{x}
if fnValue.Call(args)[0].Bool() {
outValue = reflect.Append(outValue, x)
}
}
return outValue.Interface()
}
func Map(in interface{}, fn interface{}) interface{} {
var (
inValue = reflect.ValueOf(in)
inValueLen = inValue.Len()
fnValue = reflect.ValueOf(fn)
fnOutType = reflect.TypeOf(fn).Out(0)
outType = reflect.SliceOf(fnOutType)
outValue = reflect.MakeSlice(outType, 0, inValueLen)
)
for i := 0; i < inValueLen; i++ {
args := []reflect.Value{inValue.Index(i)}
rets := fnValue.Call(args)
outValue = reflect.Append(outValue, rets[0])
}
return outValue.Interface()
}
func Reduce(in interface{}, fn interface{}, acc interface{}) interface{} {
var (
inValue = reflect.ValueOf(in)
inValueLen = inValue.Len()
fnValue = reflect.ValueOf(fn)
accValue = reflect.ValueOf(acc)
)
for i := 0; i < inValueLen; i++ {
args := []reflect.Value{accValue, inValue.Index(i)}
accValue = fnValue.Call(args)[0]
}
return accValue.Interface()
}
func ForEach(in interface{}, fn interface{}) {
var (
inValue = reflect.ValueOf(in)
inValueLen = inValue.Len()
fnValue = reflect.ValueOf(fn)
)
for i := 0; i < inValueLen; i++ {
args := []reflect.Value{inValue.Index(i)}
_ = fnValue.Call(args)
}
}
func Tap(in interface{}, fn interface{}) interface{} {
var (
inValue = reflect.ValueOf(in)
inValueLen = inValue.Len()
fnValue = reflect.ValueOf(fn)
)
for i := 0; i < inValueLen; i++ {
args := []reflect.Value{inValue.Index(i)}
_ = fnValue.Call(args)
}
return in
}
type wrapped struct {
value interface{}
}
func Wrap(in interface{}) wrapped {
return wrapped{in}
}
func (w wrapped) Map(fn interface{}) wrapped {
return wrapped{Map(w.value, fn)}
}
func (w wrapped) Filter(fn interface{}) wrapped {
return wrapped{Filter(w.value, fn)}
}
func (w wrapped) Reduce(fn interface{}, acc interface{}) wrapped {
return wrapped{Reduce(w.value, fn, acc)}
}
func (w wrapped) ForEach(fn interface{}) {
ForEach(w.value, fn)
}
func (w wrapped) Tap(fn interface{}) wrapped {
return wrapped{Tap(w.value, fn)}
}
func (w wrapped) Val() interface{} {
return w.value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment