Skip to content

Commit 2827f6b

Browse files
author
ahl5esoft
committed
feat: Value(res interface{})支持传入reflect.Value
1 parent 94ea294 commit 2827f6b

File tree

6 files changed

+186
-80
lines changed

6 files changed

+186
-80
lines changed

README.md

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
\_/__/
1010
```
1111

12-
# Underscore.go [![GoDoc](https://godoc.org/github.com/ahl5esoft/golang-underscore?status.svg)](https://godoc.org/github.com/ahl5esoft/golang-underscore) [![Go Report Card](https://goreportcard.com/badge/github.com/ahl5esoft/golang-underscore)](https://goreportcard.com/report/github.com/ahl5esoft/golang-underscore) ![Version](https://img.shields.io/badge/version-2.3.0-green.svg)
12+
# Underscore.go [![GoDoc](https://godoc.org/github.com/ahl5esoft/golang-underscore?status.svg)](https://godoc.org/github.com/ahl5esoft/golang-underscore) [![Go Report Card](https://goreportcard.com/badge/github.com/ahl5esoft/golang-underscore)](https://goreportcard.com/report/github.com/ahl5esoft/golang-underscore) ![Version](https://img.shields.io/badge/version-2.4.0-green.svg)
1313
like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for Go
1414

1515
## Installation
@@ -57,6 +57,7 @@ like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for G
5757
* [`Sort`](#order), [`SortBy`](#orderBy)
5858
* [`Take`](#take)
5959
* [`Uniq`](#distinct), [`UniqBy`](#distinctBy)
60+
* [`Value`](#value)
6061
* [`Values`](#values)
6162
* [`Where`](#where), [`WhereBy`](#whereBy)
6263

@@ -526,15 +527,11 @@ __Arguments__
526527
__Examples__
527528

528529
```go
529-
src := []string{ "a", "b" }
530-
var res map[string]string
531-
Chain(src).Index(func (r string, _ int) string {
532-
return r
530+
src := []string{"a", "b"}
531+
res := make(map[string]string)
532+
Chain(src).Index(func(item string, _ int) string {
533+
return item
533534
}).Value(&res)
534-
// or
535-
res := Index(src, func (r string, _ int) string {
536-
return r
537-
}).(map[string]string)
538535
// res = map[a:a b:b]
539536
```
540537

@@ -555,10 +552,8 @@ arr := []testModel{
555552
{ID: 3, Name: "b"},
556553
{ID: 4, Name: "b"},
557554
}
558-
var res map[int]testModel
555+
res := make(map[string]testModel)
559556
Chain(arr).IndexBy("id").Value(&res)
560-
// or
561-
res := IndexBy(arr, "id").(map[int]testModel)
562557
// res = map[1:{{0} 1 a} 2:{{0} 2 a} 3:{{0} 3 b} 4:{{0} 4 b}]
563558
```
564559

@@ -987,6 +982,43 @@ Chain(src).Take(1).Value(&dst)
987982
// res = [1]
988983
```
989984

985+
<a name="value" />
986+
987+
### Value(res interface{})
988+
989+
__Arguments__
990+
991+
* `res` - array or slice or reflect.Value(array) or reflect.Value(map)
992+
993+
__Examples__
994+
995+
```go
996+
resValue := reflect.New(
997+
reflect.SliceOf(
998+
reflect.TypeOf(1),
999+
),
1000+
)
1001+
Chain([]string{"a", "b"}).Map(func(_ string, i int) int {
1002+
return i
1003+
}).Value(resValue)
1004+
// resValue = &[0 1]
1005+
1006+
src := []testModel{
1007+
{ID: 1, Name: "a"},
1008+
{ID: 2, Name: "a"},
1009+
{ID: 3, Name: "b"},
1010+
{ID: 4, Name: "b"},
1011+
}
1012+
resValue := reflect.New(
1013+
reflect.MapOf(
1014+
reflect.TypeOf(src[0].Name),
1015+
reflect.TypeOf(src),
1016+
),
1017+
)
1018+
Chain(src).GroupBy("name").Value(resValue)
1019+
// res = &map[even:[2 4] odd:[1 3 5]]
1020+
```
1021+
9901022
<a name="values" />
9911023

9921024
### Values() IEnumerable

aggregate_test.go

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,32 @@ import (
77
)
88

99
func Benchmark_Aggregate(b *testing.B) {
10-
for n := 0; n < b.N; n++ {
11-
total := 0
12-
Range(1, 100, 1).Aggregate(
13-
func(memo []int, r, _ int) []int {
14-
memo = append(memo, r)
15-
memo = append(memo, -r)
16-
return memo
17-
},
18-
make([]int, 0),
19-
).Value(&total)
20-
}
21-
}
10+
b.Run("default", func(b *testing.B) {
11+
for n := 0; n < b.N; n++ {
12+
total := 0
13+
Range(1, 100, 1).Aggregate(
14+
func(memo []int, r, _ int) []int {
15+
memo = append(memo, r)
16+
memo = append(memo, -r)
17+
return memo
18+
},
19+
make([]int, 0),
20+
).Value(&total)
21+
}
22+
})
2223

23-
func Benchmark_Aggregate_NoValue(b *testing.B) {
24-
for n := 0; n < b.N; n++ {
25-
Range(1, 100, 1).Aggregate(
26-
func(memo []int, r, _ int) []int {
27-
memo = append(memo, r)
28-
memo = append(memo, -r)
29-
return memo
30-
},
31-
make([]int, 0),
32-
)
33-
}
24+
b.Run("no value", func(b *testing.B) {
25+
for n := 0; n < b.N; n++ {
26+
Range(1, 100, 1).Aggregate(
27+
func(memo []int, r, _ int) []int {
28+
memo = append(memo, r)
29+
memo = append(memo, -r)
30+
return memo
31+
},
32+
make([]int, 0),
33+
)
34+
}
35+
})
3436
}
3537

3638
func Test_Aggregate(t *testing.T) {

group.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package underscore
22

3-
import "reflect"
3+
import (
4+
"reflect"
5+
)
46

57
func (m enumerable) Group(keySelector interface{}) enumerable {
68
return enumerable{

group_test.go

Lines changed: 79 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package underscore
22

33
import (
4+
"reflect"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
@@ -18,51 +19,90 @@ func Benchmark_Group(b *testing.B) {
1819
}
1920
}
2021

21-
func Benchmark_Group_New(b *testing.B) {
22-
for n := 0; n < b.N; n++ {
23-
dst := make([]int, 0)
24-
Range(1, benchmarkSize, 1).Group(func(n, _ int) string {
22+
func Test_Group(t *testing.T) {
23+
t.Run("default", func(t *testing.T) {
24+
res := make(map[string][]int)
25+
Chain([]int{1, 2, 3, 4, 5}).Group(func(n, _ int) string {
2526
if n%2 == 0 {
2627
return "even"
2728
}
2829
return "odd"
29-
}).Value(&dst)
30-
}
31-
}
30+
}).Value(&res)
31+
assert.EqualValues(
32+
t,
33+
res,
34+
map[string][]int{
35+
"odd": {1, 3, 5},
36+
"even": {2, 4},
37+
},
38+
)
39+
})
3240

33-
func Test_Group(t *testing.T) {
34-
res := make(map[string][]int)
35-
Chain([]int{1, 2, 3, 4, 5}).Group(func(n, _ int) string {
36-
if n%2 == 0 {
37-
return "even"
38-
}
39-
return "odd"
40-
}).Value(&res)
41-
assert.EqualValues(
42-
t,
43-
res,
44-
map[string][]int{
45-
"odd": {1, 3, 5},
46-
"even": {2, 4},
47-
},
48-
)
41+
t.Run("reflect.Value", func(t *testing.T) {
42+
resValue := reflect.New(
43+
reflect.MapOf(
44+
reflect.TypeOf(""),
45+
reflect.TypeOf([]int{}),
46+
),
47+
)
48+
Chain([]int{1, 2, 3, 4, 5}).Group(func(n, _ int) string {
49+
if n%2 == 0 {
50+
return "even"
51+
}
52+
return "odd"
53+
}).Value(resValue)
54+
assert.EqualValues(
55+
t,
56+
resValue.Interface(),
57+
map[string][]int{
58+
"odd": {1, 3, 5},
59+
"even": {2, 4},
60+
},
61+
)
62+
})
4963
}
5064

5165
func Test_GroupBy(t *testing.T) {
52-
src := []testModel{
53-
{ID: 1, Name: "a"},
54-
{ID: 2, Name: "a"},
55-
{ID: 3, Name: "b"},
56-
{ID: 4, Name: "b"},
57-
}
58-
res := make(map[string][]testModel)
59-
Chain(src).GroupBy("Name").Value(&res)
60-
assert.EqualValues(
61-
t,
62-
res,
63-
map[string][]testModel{
64-
"a": {src[0], src[1]},
65-
"b": {src[2], src[3]},
66-
},
67-
)
66+
t.Run("default", func(t *testing.T) {
67+
src := []testModel{
68+
{ID: 1, Name: "a"},
69+
{ID: 2, Name: "a"},
70+
{ID: 3, Name: "b"},
71+
{ID: 4, Name: "b"},
72+
}
73+
res := make(map[string][]testModel)
74+
Chain(src).GroupBy("Name").Value(&res)
75+
assert.EqualValues(
76+
t,
77+
res,
78+
map[string][]testModel{
79+
"a": {src[0], src[1]},
80+
"b": {src[2], src[3]},
81+
},
82+
)
83+
})
84+
85+
t.Run("reflect.Value", func(t *testing.T) {
86+
src := []testModel{
87+
{ID: 1, Name: "a"},
88+
{ID: 2, Name: "a"},
89+
{ID: 3, Name: "b"},
90+
{ID: 4, Name: "b"},
91+
}
92+
res := reflect.New(
93+
reflect.MapOf(
94+
reflect.TypeOf(src[0].Name),
95+
reflect.TypeOf(src),
96+
),
97+
)
98+
Chain(src).GroupBy("name").Value(res)
99+
assert.EqualValues(
100+
t,
101+
res.Elem().Interface(),
102+
map[string][]testModel{
103+
"a": {src[0], src[1]},
104+
"b": {src[2], src[3]},
105+
},
106+
)
107+
})
68108
}

map_test.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package underscore
22

33
import (
4+
"fmt"
5+
"reflect"
46
"strconv"
57
"testing"
68

79
"github.com/stretchr/testify/assert"
810
)
911

1012
func Test_Map(t *testing.T) {
11-
t.Run("ok", func(t *testing.T) {
13+
t.Run("default", func(t *testing.T) {
1214
src := []string{"11", "12", "13"}
1315
var res []int
1416
Chain(src).Map(func(s string, _ int) int {
@@ -22,7 +24,7 @@ func Test_Map(t *testing.T) {
2224
)
2325
})
2426

25-
t.Run("ptr", func(t *testing.T) {
27+
t.Run("元素是指针", func(t *testing.T) {
2628
src := []string{"11", "12", "13"}
2729
var res []*string
2830
Chain(src).Map(func(r string, _ int) *string {
@@ -34,6 +36,25 @@ func Test_Map(t *testing.T) {
3436
[]*string{&src[0], &src[1], &src[2]},
3537
)
3638
})
39+
40+
t.Run("结果为reflect.Value", func(t *testing.T) {
41+
resValue := reflect.New(
42+
reflect.SliceOf(
43+
reflect.TypeOf(1),
44+
),
45+
)
46+
Chain([]string{"a", "b"}).Map(func(_ string, i int) int {
47+
return i
48+
}).Value(resValue)
49+
assert.EqualValues(
50+
t,
51+
resValue.Elem().Interface(),
52+
[]int{0, 1},
53+
)
54+
fmt.Println(resValue)
55+
56+
assert.True(t, false)
57+
})
3758
}
3859

3960
func Test_MapBy(t *testing.T) {

value.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
package underscore
22

3-
import "reflect"
3+
import (
4+
"reflect"
5+
)
46

57
func (m enumerable) Value(res interface{}) {
6-
resValue := reflect.ValueOf(res)
8+
var resValue reflect.Value
9+
var ok bool
10+
if resValue, ok = res.(reflect.Value); !ok {
11+
resValue = reflect.ValueOf(res)
12+
}
13+
714
switch resValue.Elem().Kind() {
815
case reflect.Array, reflect.Slice:
916
m.valueToArrayOrSlice(resValue)
@@ -33,7 +40,9 @@ func (m enumerable) valueToArrayOrSlice(resValue reflect.Value) {
3340

3441
func (m enumerable) valueToMap(resValue reflect.Value) {
3542
iterator := m.GetEnumerator()
36-
mapValue := resValue.Elem()
43+
mapValue := reflect.MakeMap(
44+
resValue.Elem().Type(),
45+
)
3746
for ok := iterator.MoveNext(); ok; ok = iterator.MoveNext() {
3847
mapValue.SetMapIndex(
3948
iterator.GetKey(),

0 commit comments

Comments
 (0)