diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..919ce1f
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..639900d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..25be34f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dsl.go b/dsl.go
new file mode 100644
index 0000000..dec4929
--- /dev/null
+++ b/dsl.go
@@ -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
+}
+
+
diff --git a/dsl_test.go b/dsl_test.go
new file mode 100644
index 0000000..a7dc676
--- /dev/null
+++ b/dsl_test.go
@@ -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))
+}
+
diff --git a/execute.go b/execute.go
new file mode 100644
index 0000000..1dd307b
--- /dev/null
+++ b/execute.go
@@ -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
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..2060b19
--- /dev/null
+++ b/go.mod
@@ -0,0 +1 @@
+module "hy-go-function"
\ No newline at end of file
diff --git a/hy-go-function.iml b/hy-go-function.iml
new file mode 100644
index 0000000..eacc75a
--- /dev/null
+++ b/hy-go-function.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/internal/do_filter.go b/internal/do_filter.go
new file mode 100644
index 0000000..f4b7b9e
--- /dev/null
+++ b/internal/do_filter.go
@@ -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()
+}
diff --git a/internal/do_flatmap.go b/internal/do_flatmap.go
new file mode 100644
index 0000000..e04cbbd
--- /dev/null
+++ b/internal/do_flatmap.go
@@ -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()
+}
+
diff --git a/internal/do_map.go b/internal/do_map.go
new file mode 100644
index 0000000..433176c
--- /dev/null
+++ b/internal/do_map.go
@@ -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()
+}