-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package hy_go_function | ||
|
||
type operation string | ||
|
||
const ( | ||
filter = operation("filter") | ||
maps = operation("map") | ||
flatMap = operation("flatmap") | ||
) | ||
|
||
type DSL struct { | ||
function []interface{} | ||
value interface{} | ||
operations []operation | ||
} | ||
|
||
func Of(value interface{}) DSL { | ||
return DSL{ | ||
value: value, | ||
} | ||
} | ||
|
||
func (d DSL) Filter(predicate interface{}) DSL { | ||
d.operations = append(d.operations, filter) | ||
d.function = append(d.function, predicate) | ||
return d | ||
} | ||
|
||
func (d DSL) FlatMap(function interface{}) DSL { | ||
d.operations = append(d.operations, flatMap) | ||
d.function = append(d.function, function) | ||
return d | ||
} | ||
|
||
func (d DSL) Map(function interface{}) DSL { | ||
d.operations = append(d.operations, maps) | ||
d.function = append(d.function, function) | ||
return d | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package hy_go_function | ||
|
||
import ( | ||
"fmt" | ||
"hy-go-function/internal" | ||
"strconv" | ||
"testing" | ||
) | ||
|
||
func Test_Stream(t *testing.T) { | ||
array := []string{ | ||
"1", "2", "3", | ||
} | ||
result := Of(array).Map(func(i string) int { | ||
atoi, err := strconv.Atoi(i) | ||
if err != nil { | ||
return 0 | ||
} | ||
return atoi | ||
}).Filter(func(i int) bool { | ||
if i == 1 { | ||
return false | ||
} | ||
return true | ||
}).Map(func(i int) int { | ||
return i + 5 | ||
}).Execute() | ||
|
||
println(fmt.Sprintf("result : %v", result)) | ||
} | ||
|
||
func Test_filterEmpty(t *testing.T) { | ||
array := []string{ | ||
} | ||
result := internal.DoFilter(array, func(i string) bool { | ||
if i == "1" { | ||
return false | ||
} | ||
return true | ||
}) | ||
|
||
println(fmt.Sprintf("result : %v", result)) | ||
} | ||
|
||
func Test_filter(t *testing.T) { | ||
array := []string{ | ||
"1", "2", "3", | ||
} | ||
result := internal.DoFilter(array, func(i string) bool { | ||
if i == "1" { | ||
return false | ||
} | ||
return true | ||
}) | ||
|
||
println(fmt.Sprintf("result : %v", result)) | ||
|
||
result2 := internal.DoFilter(1, func(i int) bool { | ||
if i != 1 { | ||
return false | ||
} | ||
return true | ||
}) | ||
|
||
println(fmt.Sprintf("result : %v", result2)) | ||
} | ||
|
||
func Test_mapEmpty(t *testing.T) { | ||
array := []string{ | ||
} | ||
result := internal.DoMap(array, func(i string) int { | ||
if i == "1" { | ||
return 1 | ||
} | ||
return 2 | ||
}) | ||
|
||
println(fmt.Sprintf("result : %v", result)) | ||
} | ||
|
||
func Test_map(t *testing.T) { | ||
array := []string{ | ||
"1", "2", "3", | ||
} | ||
result := internal.DoMap(array, func(i string) int { | ||
if i == "1" { | ||
return 1 | ||
} | ||
return 2 | ||
}) | ||
|
||
println(fmt.Sprintf("result : %v", result)) | ||
|
||
result2 := internal.DoMap(1, func(i int) int { return i + 1}) | ||
|
||
println(fmt.Sprintf("result2 : %v", result2)) | ||
} | ||
func Test_flatmap(t *testing.T) { | ||
array := [][]string{ | ||
{"1", "2", "3"}, | ||
{"1", "2", "3"}, | ||
} | ||
result := internal.DoFlatMap(array, func(i []string) []string { | ||
return i | ||
}) | ||
|
||
println(fmt.Sprintf("result : %v", result)) | ||
|
||
result2 := internal.DoMap(1, func(i int) int { return i + 1}) | ||
|
||
println(fmt.Sprintf("result2 : %v", result2)) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package hy_go_function | ||
|
||
import "hy-go-function/internal" | ||
|
||
func (d DSL) Execute() interface{} { | ||
for i, operation := range d.operations { | ||
if d.value == nil { | ||
return nil | ||
} | ||
|
||
switch operation { | ||
case filter: | ||
d.value = internal.DoFilter(d.value, d.function[i]) | ||
case maps: | ||
d.value = internal.DoMap(d.value, d.function[i]) | ||
case flatMap: | ||
d.value = internal.DoFlatMap(d.value, d.function[i]) | ||
} | ||
} | ||
return d.value | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module "hy-go-function" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module type="WEB_MODULE" version="4"> | ||
<component name="Go" enabled="true" /> | ||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | ||
<exclude-output /> | ||
<content url="file://$MODULE_DIR$" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
</component> | ||
</module> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package internal | ||
|
||
import "reflect" | ||
|
||
func DoFilter(array interface{}, predicate interface{}) interface{} { | ||
funcValue := reflect.ValueOf(predicate) | ||
funcType := funcValue.Type() | ||
|
||
if funcType.Out(0).Kind() != reflect.Bool { | ||
panic("type not boolean") | ||
} | ||
|
||
inValue := reflect.ValueOf(array) | ||
inType := inValue.Type() | ||
|
||
if inType.Kind() != reflect.Slice && inType.Kind() != reflect.Array { | ||
result := funcValue.Call([]reflect.Value{inValue})[0].Interface().(bool) | ||
if result { | ||
return inValue | ||
} else { | ||
return nil | ||
} | ||
} | ||
|
||
resultSliceType := reflect.SliceOf(inType.Elem()) | ||
resultSlice := reflect.MakeSlice(resultSliceType, 0, 0) | ||
|
||
for i := 0; i < inValue.Len(); i++ { | ||
elem := inValue.Index(i) | ||
result := funcValue.Call([]reflect.Value{elem})[0].Interface().(bool) | ||
if result { | ||
resultSlice = reflect.Append(resultSlice, elem) | ||
} | ||
} | ||
|
||
return resultSlice.Interface() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package internal | ||
|
||
import ( | ||
"reflect" | ||
) | ||
|
||
func DoFlatMap(input interface{}, function interface{}) interface{} { | ||
funcValue := reflect.ValueOf(function) | ||
funcType := funcValue.Type() | ||
|
||
inValue := reflect.ValueOf(input) | ||
inType := inValue.Type() | ||
if inType.Kind() != reflect.Slice && inType.Kind() != reflect.Array { | ||
result := funcValue.Call([]reflect.Value{inValue})[0] | ||
return result.Interface() | ||
} | ||
|
||
resultSliceType := reflect.SliceOf(funcType.Out(0).Elem()) | ||
resultSlice := reflect.MakeSlice(resultSliceType, 0, 0) | ||
for i := 0; i < inValue.Len(); i++ { | ||
elem := inValue.Index(i) | ||
result := funcValue.Call([]reflect.Value{elem})[0] | ||
for j := 0; j < result.Len(); j++ { | ||
e := result.Index(j) | ||
resultSlice = reflect.Append(resultSlice, e) | ||
} | ||
} | ||
|
||
return resultSlice.Interface() | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package internal | ||
|
||
import "reflect" | ||
|
||
func DoMap(input interface{}, function interface{}) interface{} { | ||
funcValue := reflect.ValueOf(function) | ||
funcType := funcValue.Type() | ||
|
||
inValue := reflect.ValueOf(input) | ||
inType := inValue.Type() | ||
if inType.Kind() != reflect.Slice && inType.Kind() != reflect.Array { | ||
result := funcValue.Call([]reflect.Value{inValue})[0] | ||
return result.Interface() | ||
} | ||
|
||
resultSliceType := reflect.SliceOf(funcType.Out(0)) | ||
resultSlice := reflect.MakeSlice(resultSliceType, 0, 0) | ||
for i := 0; i < inValue.Len(); i++ { | ||
elem := inValue.Index(i) | ||
result := funcValue.Call([]reflect.Value{elem})[0] | ||
resultSlice = reflect.Append(resultSlice, result) | ||
} | ||
|
||
return resultSlice.Interface() | ||
} |