Skip to content

Commit 4964789

Browse files
committed
feat: Except/ExceptBy/Reject/RejectBy/Reverse/ReverseBy
1 parent 0036d53 commit 4964789

9 files changed

+298
-147
lines changed

Diff for: README.md

+111-15
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.1.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.1.1-green.svg)
1313
like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for Go
1414

1515
## Installation
@@ -19,7 +19,7 @@ like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for G
1919
$ go get -u github.com/ahl5esoft/golang-underscore
2020

2121
## Lack
22-
* Except/ExceptBy/Reject/RejectBy/Reverse/ReverseBy/ThenBy
22+
* ThenBy
2323

2424
## Documentation
2525

@@ -48,6 +48,8 @@ like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for G
4848
* [`Property`](#property), [`PropertyRV`](#propertyRV)
4949
* [`Range`](#range)
5050
* [`Reduce`](#aggregate)
51+
* [`Reject`](#reject), [`RejectBy`](#rejectBy)
52+
* [`Reverse`](#reverse), [`ReverseBy`](#reverseBy)
5153
* [`Select`](#select), [`SelectBy`](#selectBy)
5254
* [`SelectMany`](#selectMany), [`SelectManyBy`](#selectManyBy)
5355
* [`Size`](#count)
@@ -113,11 +115,11 @@ ok := Chain([]testModel{
113115

114116
<a name="allBy" />
115117

116-
### AllBy(properties) bool
118+
### AllBy(fields) bool
117119

118120
__Arguments__
119121

120-
* `properties` - map[string]interface{}
122+
* `fields` - map[string]interface{}
121123

122124
__Return__
123125

@@ -163,11 +165,11 @@ ok := Chain([]testModel{
163165

164166
<a name="anyBy" />
165167

166-
### AnyBy(properties) bool
168+
### AnyBy(fields) bool
167169

168170
__Arguments__
169171

170-
* `properties` - map[string]interface{}
172+
* `fields` - map[string]interface{}
171173

172174
__Return__
173175

@@ -323,11 +325,11 @@ Chain([][]int{
323325

324326
<a name="findBy" />
325327

326-
### FindBy(properties) IEnumerable
328+
### FindBy(fields) IEnumerable
327329

328330
__Arguments__
329331

330-
* `properties` - map[string]interface{}
332+
* `fields` - map[string]interface{}
331333

332334
__Examples__
333335

@@ -372,11 +374,11 @@ index := Chain(src).FindIndex(func(r testModel, _ int) bool {
372374

373375
<a name="findIndexBy" />
374376

375-
### FindIndexBy(properties) int
377+
### FindIndexBy(fields) int
376378

377379
__Arguments__
378380

379-
* `properties` - map[string]interface{}
381+
* `fields` - map[string]interface{}
380382

381383
__Return__
382384

@@ -530,12 +532,12 @@ if IsArray(map[string]int{}) {
530532

531533
<a name="isMatch" />
532534

533-
### IsMatch(element, properties) bool
535+
### IsMatch(element, fields) bool
534536

535537
__Arguments__
536538

537539
* `element` - object
538-
* `properties` - map[string]interface{}
540+
* `fields` - map[string]interface{}
539541

540542
__Examples__
541543

@@ -763,6 +765,100 @@ Range2(0, 3, 2).Value(&res)
763765
// res = [0 2]
764766
```
765767

768+
<a name="reject" />
769+
770+
### Reject(predicate) IEnumerable
771+
772+
__Arguments__
773+
774+
* `predicate` - func(element or value, index or key) bool
775+
776+
__Examples__
777+
778+
```go
779+
arr := []int{1, 2, 3, 4}
780+
var res []int
781+
Chain(arr).Reject(func(n, i int) bool {
782+
return n%2 == 0
783+
}).Value(&res)
784+
// res = [1, 3]
785+
```
786+
787+
__Same__
788+
789+
* `Except`
790+
791+
<a name="rejectBy" />
792+
793+
### RejectBy(fields) IEnumerable
794+
795+
__Arguments__
796+
797+
* `fields` - map[string]interface{}
798+
799+
__Examples__
800+
801+
```go
802+
arr := []testModel{
803+
{ID: 1, Name: "one"},
804+
{ID: 2, Name: "two"},
805+
{ID: 3, Name: "three"},
806+
}
807+
var res []testModel
808+
Chain(arr).RejectBy(map[string]interface{}{
809+
"Id": 1,
810+
}).Value(&res)
811+
// res = []testModel{ {ID: 2, Name: "two"}, {ID: 3, Name: "three"} }
812+
```
813+
814+
__Same__
815+
816+
* `ExceptBy`
817+
818+
<a name="reverse" />
819+
820+
### Reverse(selector) IEnumerable
821+
822+
__Arguments__
823+
824+
* `selector` - func(element, index or key) anyType
825+
826+
__Examples__
827+
828+
```go
829+
src := []testModel{
830+
{ID: 2, Name: "two"},
831+
{ID: 1, Name: "one"},
832+
{ID: 3, Name: "three"},
833+
}
834+
var res []testModel
835+
Chain(src).Reverse(func(r testModel, _ int) int {
836+
return r.ID
837+
}).Value(&res)
838+
// res = []testModel{ {ID: 3, Name: "three"}, {ID: 2, Name: "two"}, {ID: 1, Name: "one"} }
839+
```
840+
841+
<a name="reverseBy" />
842+
843+
### ReverseBy(fieldName) IEnumerable
844+
845+
__Arguments__
846+
847+
* `fieldName` - string
848+
849+
__Examples__
850+
851+
```go
852+
src := []testModel{
853+
{ID: 2, Name: "two"},
854+
{ID: 1, Name: "one"},
855+
{ID: 3, Name: "three"},
856+
}
857+
var res []testModel
858+
Chain(src).ReverseBy("id").Value(&res)
859+
// res = []testModel{ {ID: 3, Name: "three"}, {ID: 2, Name: "two"}, {ID: 1, Name: "one"} }
860+
```
861+
766862
<a name="select" />
767863

768864
### Select(selector) IEnumerable
@@ -946,11 +1042,11 @@ __Same__
9461042

9471043
<a name="whereBy" />
9481044

949-
### WhereBy(properties) IEnumerable
1045+
### WhereBy(fields) IEnumerable
9501046

9511047
__Arguments__
9521048

953-
* `properties` - map[string]interface{}
1049+
* `fields` - map[string]interface{}
9541050

9551051
__Examples__
9561052

@@ -974,7 +1070,7 @@ __Same__
9741070

9751071
## Release Notes
9761072
~~~
977-
v2.1.0 (2019-06-27)
1073+
v2.1.0 (2020-11-17)
9781074
* IEnumerable增加Order、OrderBy、Sort、SortBy
9791075
* IEnumerable.Aggregate(memo interface{}, fn interface{}) -> IEnumerable.Aggregate(fn interface{}, memo interface{})
9801076
~~~

Diff for: except.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package underscore
2+
3+
func (m enumerable) Except(predicate interface{}) IEnumerable {
4+
return m.Reject(predicate)
5+
}
6+
7+
func (m enumerable) ExceptBy(dict map[string]interface{}) IEnumerable {
8+
return m.RejectBy(dict)
9+
}

Diff for: except_test.go

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package underscore
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_Except(t *testing.T) {
10+
arr := []int{1, 2, 3, 4}
11+
var res []int
12+
Chain(arr).Except(func(n, i int) bool {
13+
return n%2 == 0
14+
}).Value(&res)
15+
assert.EqualValues(
16+
t,
17+
res,
18+
[]int{1, 3},
19+
)
20+
}
21+
22+
func Test_ExceptBy(t *testing.T) {
23+
arr := []testModel{
24+
{ID: 1, Name: "one"},
25+
{ID: 2, Name: "two"},
26+
{ID: 3, Name: "three"},
27+
}
28+
var res []testModel
29+
Chain(arr).ExceptBy(map[string]interface{}{
30+
"Id": 1,
31+
}).Value(&res)
32+
assert.EqualValues(
33+
t,
34+
res,
35+
[]testModel{
36+
{ID: 2, Name: "two"},
37+
{ID: 3, Name: "three"},
38+
},
39+
)
40+
}

Diff for: i-enumerable.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ package underscore
44
type IEnumerable interface {
55
Aggregate(memo interface{}, fn interface{}) IEnumerable
66
All(predicate interface{}) bool
7-
AllBy(dict map[string]interface{}) bool
7+
AllBy(fields map[string]interface{}) bool
88
Any(predicate interface{}) bool
9-
AnyBy(dict map[string]interface{}) bool
9+
AnyBy(fields map[string]interface{}) bool
1010
Count() int
1111
Distinct(selector interface{}) IEnumerable
1212
DistinctBy(fieldName string) IEnumerable
1313
Each(action interface{})
14+
Except(predicate interface{}) IEnumerable
15+
ExceptBy(fields map[string]interface{}) IEnumerable
1416
Filter(predicate interface{}) IEnumerable
15-
FilterBy(dict map[string]interface{}) IEnumerable
17+
FilterBy(fields map[string]interface{}) IEnumerable
1618
Find(predicate interface{}) IEnumerable
17-
FindBy(dict map[string]interface{}) IEnumerable
19+
FindBy(fields map[string]interface{}) IEnumerable
1820
FindIndex(predicate interface{}) int
19-
FindIndexBy(dict map[string]interface{}) int
21+
FindIndexBy(fields map[string]interface{}) int
2022
First() IEnumerable
2123
GetEnumerator() IEnumerator
2224
Group(keySelector interface{}) enumerable
@@ -32,6 +34,10 @@ type IEnumerable interface {
3234
Order(selector interface{}) IEnumerable
3335
OrderBy(fieldName string) IEnumerable
3436
Reduce(memo interface{}, fn interface{}) IEnumerable
37+
Reject(predicate interface{}) IEnumerable
38+
RejectBy(fields map[string]interface{}) IEnumerable
39+
Reverse(selector interface{}) IEnumerable
40+
ReverseBy(fieldName string) IEnumerable
3541
Select(selector interface{}) IEnumerable
3642
SelectBy(fieldName string) IEnumerable
3743
SelectMany(selector interface{}) IEnumerable
@@ -46,5 +52,5 @@ type IEnumerable interface {
4652
Value(res interface{})
4753
Values() IEnumerable
4854
Where(predicate interface{}) IEnumerable
49-
WhereBy(dict map[string]interface{}) IEnumerable
55+
WhereBy(fields map[string]interface{}) IEnumerable
5056
}

Diff for: order.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func (m enumerable) Order(selector interface{}) IEnumerable {
1818

1919
func (m enumerable) OrderBy(fieldName string) IEnumerable {
2020
getter := PropertyRV(fieldName)
21-
return m.Sort(func(value, _ interface{}) facade {
21+
return m.Order(func(value, _ interface{}) facade {
2222
return facade{
2323
getter(value),
2424
}

Diff for: reject.go

+30
Original file line numberDiff line numberDiff line change
@@ -1 +1,31 @@
11
package underscore
2+
3+
import "reflect"
4+
5+
func (m enumerable) Reject(predicate interface{}) IEnumerable {
6+
return enumerable{
7+
Enumerator: func() IEnumerator {
8+
iterator := m.GetEnumerator()
9+
predicateRV := reflect.ValueOf(predicate)
10+
return &enumerator{
11+
MoveNextFunc: func() (valueRV reflect.Value, keyRV reflect.Value, ok bool) {
12+
for ok = iterator.MoveNext(); ok; ok = iterator.MoveNext() {
13+
valueRV = iterator.GetValue()
14+
keyRV = iterator.GetKey()
15+
if !predicateRV.Call([]reflect.Value{valueRV, keyRV})[0].Bool() {
16+
return
17+
}
18+
}
19+
20+
return
21+
},
22+
}
23+
},
24+
}
25+
}
26+
27+
func (m enumerable) RejectBy(properties map[string]interface{}) IEnumerable {
28+
return m.Reject(func(v, _ interface{}) bool {
29+
return IsMatch(v, properties)
30+
})
31+
}

0 commit comments

Comments
 (0)