Skip to content

Commit 6f2dbcf

Browse files
author
ahl5esoft
committed
Reduce、Take支持IEnumerable
IEnumerable增加Aggregate、Skip IQuery删除Clone 优化IEnumerable的First、Index、Values
1 parent e31e24d commit 6f2dbcf

18 files changed

+292
-257
lines changed

README.md

Lines changed: 60 additions & 68 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-1.2.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-1.4.0-green.svg)
1313
like <a href="http://underscorejs.org/">underscore.js</a>, but for Go
1414

1515
## Installation
@@ -24,11 +24,11 @@ like <a href="http://underscorejs.org/">underscore.js</a>, but for Go
2424
## Documentation
2525

2626
### API
27+
* [`Aggregate`](#aggregate)
2728
* [`All`](#all), [`AllBy`](#allBy)
2829
* [`Any`](#any), [`AnyBy`](#anyBy)
2930
* [`AsParallel`](#asParallel)
3031
* [`Chain`](#chain)
31-
* [`Clone`](#clone)
3232
* [`Distinct`](#distinct), [`DistinctBy`](#distinctBy)
3333
* [`Each`](#each)
3434
* [`Filter`](#where), [`FilterBy`](#whereBy)
@@ -46,17 +46,44 @@ like <a href="http://underscorejs.org/">underscore.js</a>, but for Go
4646
* [`Object`](#object)
4747
* [`Property`](#property), [`PropertyRV`](#propertyRV)
4848
* [`Range`](#range)
49-
* [`Reduce`](#reduce)
49+
* [`Reduce`](#aggregate)
5050
* [`Reject`](#reject), [`RejectBy`](#rejectBy)
5151
* [`Reverse`](#reverse), [`ReverseBy`](#reverseBy)
5252
* [`Select`](#select), [`SelectBy`](#selectBy)
5353
* [`Size`](#size)
54+
* [`Skip`](#skip)
5455
* [`Sort`](#sort), [`SortBy`](#sortBy)
5556
* [`Take`](#take)
5657
* [`Uniq`](#distinct), [`UniqBy`](#distinctBy)
5758
* [`Values`](#values)
5859
* [`Where`](#where), [`WhereBy`](#whereBy)
5960

61+
<a name="aggregate" />
62+
63+
### Aggregate(memo, fn) IEnumerable
64+
### Aggregate(source, iterator) IQuery
65+
66+
__Arguments__
67+
68+
* `memo` - anyType
69+
* `iterator` - func(memo, element or value, key or index) memo
70+
71+
__Examples__
72+
73+
```go
74+
dst := make([]int, 0)
75+
Chain2([]int{1, 2}).Aggregate(make([]int, 0), func(memo []int, n, _ int) []int {
76+
memo = append(memo, n)
77+
memo = append(memo, n+10)
78+
return memo
79+
}).Value(&dst)
80+
// dst = [1 11 2 12]
81+
```
82+
83+
__Same__
84+
85+
* `Reduce`
86+
6087
<a name="all" />
6188

6289
### All(predicate) bool
@@ -200,28 +227,6 @@ Chain([]int{1, 2, 1, 4, 1, 3}).Uniq(nil).Group(func(n, _ int) string {
200227
// len(res) == 2 && ok == true
201228
```
202229

203-
<a name="clone" />
204-
205-
### Clone()
206-
207-
__Return__
208-
209-
* interface{}
210-
211-
__Examples__
212-
213-
```go
214-
arr := []int{1, 2, 3}
215-
var duplicate []int
216-
Chain(arr).Clone().Value(&duplicate)
217-
// or
218-
duplicate := Clone(arr)
219-
ok := All(duplicate, func(n, i int) bool {
220-
return arr[i] == n
221-
})
222-
// ok == true
223-
```
224-
225230
<a name="distinct" />
226231

227232
### Distinct(selector) IEnumerable
@@ -842,38 +847,6 @@ Range2(0, 3, 2).Value(&res)
842847
// res = [0 2]
843848
```
844849

845-
<a name="reduce" />
846-
847-
### Reduce(source, iterator)
848-
849-
__Arguments__
850-
851-
* `source` - array
852-
* `iterator` - func(memo, element or value, key or index) memo
853-
* `memo` - anyType
854-
855-
__Return__
856-
857-
* interface{} - memo
858-
859-
__Examples__
860-
861-
```go
862-
var res []int
863-
Chain([]int{1, 2}).Reduce(func(memo []int, n, _ int) []int {
864-
memo = append(memo, n)
865-
memo = append(memo, n+10)
866-
return memo
867-
}, make([]int, 0)).Value(&res)
868-
// or
869-
res := Reduce([]int{1, 2}, func(memo []int, n, _ int) []int {
870-
memo = append(memo, n)
871-
memo = append(memo, n+10)
872-
return memo
873-
}, make([]int, 0)).([]int)
874-
// res = [1 11 2 12]
875-
```
876-
877850
<a name="reject" />
878851

879852
### Reject(source, predicate)
@@ -1067,6 +1040,23 @@ l := Size(dict)
10671040
// l = 3
10681041
```
10691042

1043+
<a name="skip" />
1044+
1045+
### Skip(count) IEnumerable
1046+
1047+
__Arguments__
1048+
1049+
* `count` - int
1050+
1051+
__Examples__
1052+
1053+
```go
1054+
src := []int{1, 2, 3}
1055+
dst := make([]int, 0)
1056+
Chain2(src).Skip(2).Value(&dst)
1057+
// dst = [3]
1058+
```
1059+
10701060
<a name="sort" />
10711061

10721062
### Sort(source, selector)
@@ -1129,25 +1119,19 @@ res := SortBy(arr, "id").([]testModel)
11291119

11301120
<a name="take" />
11311121

1132-
### Take(source, count)
1122+
### Take(count) IEnumerable
1123+
### Take(count) IQuery
11331124

11341125
__Arguments__
11351126

1136-
* `source` - array or map
11371127
* `count` - int
11381128

1139-
__Return__
1140-
1141-
* interface{}
1142-
11431129
__Examples__
11441130

11451131
```go
1146-
arr := []int{1, 2, 3}
1147-
var res []int
1148-
Chain(arr).Take(1).Value(&res)
1149-
// or
1150-
res := Take(arr, 1).([]int)
1132+
src := []int{1, 2, 3}
1133+
dst := make([]int, 0)
1134+
Chain2(src).Take(1).Value(&dst)
11511135
// res = [1]
11521136
```
11531137

@@ -1234,6 +1218,14 @@ __Same__
12341218
* `FilterBy`
12351219

12361220
## Release Notes
1221+
~~~
1222+
v1.4.0 (2019-06-15)
1223+
* Reduce、Take支持IEnumerable
1224+
* IEnumerable增加Aggregate、Skip
1225+
* IQuery删除Clone
1226+
* 优化IEnumerable的First、Index、Values
1227+
~~~
1228+
12371229
~~~
12381230
v1.3.0 (2019-06-09)
12391231
* FindIndex、FindIndexBy、Keys、Map、MapBy、Object、Uniq、UniqBy、Values支持IEnumerable

aggregate.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package underscore
2+
3+
import "reflect"
4+
5+
func (m enumerable) Aggregate(memo interface{}, fn interface{}) IEnumerable {
6+
fnRV := reflect.ValueOf(fn)
7+
iterator := m.GetEnumerator()
8+
memoRV := reflect.ValueOf(memo)
9+
for ok := iterator.MoveNext(); ok; ok = iterator.MoveNext() {
10+
memoRV = fnRV.Call([]reflect.Value{
11+
memoRV,
12+
iterator.GetValue(),
13+
iterator.GetKey(),
14+
})[0]
15+
}
16+
return chainFromRV(memoRV)
17+
}

aggregate_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package underscore
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func Benchmark_Aggregate(b *testing.B) {
8+
for n := 0; n < b.N; n++ {
9+
total := 0
10+
Range2(1, 100, 1).Aggregate(make([]int, 0), func(memo []int, r, _ int) []int {
11+
memo = append(memo, r)
12+
memo = append(memo, -r)
13+
return memo
14+
}).Value(&total)
15+
}
16+
}
17+
18+
func Benchmark_Aggregate_NoValue(b *testing.B) {
19+
for n := 0; n < b.N; n++ {
20+
Range2(1, 100, 1).Aggregate(make([]int, 0), func(memo []int, r, _ int) []int {
21+
memo = append(memo, r)
22+
memo = append(memo, -r)
23+
return memo
24+
})
25+
}
26+
}
27+
28+
func Test_Aggregate(t *testing.T) {
29+
dst := make([]int, 0)
30+
Chain2([]int{1, 2}).Aggregate(make([]int, 0), func(memo []int, n, _ int) []int {
31+
memo = append(memo, n)
32+
memo = append(memo, n+10)
33+
return memo
34+
}).Value(&dst)
35+
if !(len(dst) == 4 && dst[0] == 1 && dst[1] == 11 && dst[2] == 2 && dst[3] == 12) {
36+
t.Error(dst)
37+
}
38+
}

chain.go

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,12 @@ func Chain(source interface{}) IQuery {
1111

1212
// Chain2 is 初始化
1313
func Chain2(src interface{}) IEnumerable {
14-
srcRV := reflect.ValueOf(src)
15-
switch srcRV.Kind() {
16-
case reflect.Array, reflect.Slice:
17-
return chainByArrayOrSlice(srcRV, srcRV.Len())
18-
case reflect.Map:
19-
return chainByMap(srcRV, srcRV.Len())
20-
default:
21-
if iterator, ok := src.(IEnumerator); ok {
22-
return enumerable{
23-
Enumerator: func() IEnumerator {
24-
return iterator
25-
},
26-
}
27-
}
28-
29-
return enumerable{
30-
Enumerator: func() IEnumerator {
31-
return nullEnumerator{
32-
Src: srcRV,
33-
}
34-
},
35-
}
36-
}
14+
return chainFromRV(
15+
reflect.ValueOf(src),
16+
)
3717
}
3818

39-
func chainByArrayOrSlice(srcRV reflect.Value, size int) IEnumerable {
19+
func chainFromArrayOrSlice(srcRV reflect.Value, size int) IEnumerable {
4020
return enumerable{
4121
Enumerator: func() IEnumerator {
4222
index := 0
@@ -56,7 +36,7 @@ func chainByArrayOrSlice(srcRV reflect.Value, size int) IEnumerable {
5636
}
5737
}
5838

59-
func chainByMap(srcRV reflect.Value, size int) IEnumerable {
39+
func chainFromMap(srcRV reflect.Value, size int) IEnumerable {
6040
return enumerable{
6141
Enumerator: func() IEnumerator {
6242
index := 0
@@ -76,3 +56,28 @@ func chainByMap(srcRV reflect.Value, size int) IEnumerable {
7656
},
7757
}
7858
}
59+
60+
func chainFromRV(rv reflect.Value) IEnumerable {
61+
switch rv.Kind() {
62+
case reflect.Array, reflect.Slice:
63+
return chainFromArrayOrSlice(rv, rv.Len())
64+
case reflect.Map:
65+
return chainFromMap(rv, rv.Len())
66+
default:
67+
if iterator, ok := rv.Interface().(IEnumerator); ok {
68+
return enumerable{
69+
Enumerator: func() IEnumerator {
70+
return iterator
71+
},
72+
}
73+
}
74+
75+
return enumerable{
76+
Enumerator: func() IEnumerator {
77+
return nullEnumerator{
78+
Src: rv,
79+
}
80+
},
81+
}
82+
}
83+
}

clone.go

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)