Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
highluck committed Jul 2, 2021
0 parents commit c8c71ef
Show file tree
Hide file tree
Showing 14 changed files with 318 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions dsl.go
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
}


113 changes: 113 additions & 0 deletions dsl_test.go
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))
}

21 changes: 21 additions & 0 deletions execute.go
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
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module "hy-go-function"
9 changes: 9 additions & 0 deletions hy-go-function.iml
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>
37 changes: 37 additions & 0 deletions internal/do_filter.go
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()
}
31 changes: 31 additions & 0 deletions internal/do_flatmap.go
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()
}

25 changes: 25 additions & 0 deletions internal/do_map.go
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()
}

0 comments on commit c8c71ef

Please sign in to comment.