Awesome
/\ \
__ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ __ ___
/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ /'_ `\ / __`\
\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ /\ \L\ \/\ \L\ \
\ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\\ \____ \ \____/
\/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_/ \/___L\ \/___/
/\____/
\_/__/
Underscore.go
like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for Go
Installation
$ go get github.com/ahl5esoft/golang-underscore
Update
$ go get -u github.com/ahl5esoft/golang-underscore
Lack
- Concat/ThenBy
Documentation
API
Aggregate
All
,AllBy
Any
,AnyBy
Chain
Count
Distinct
,DistinctBy
Each
Field
,FieldValue
Filter
,FilterBy
Find
,FindBy
FindIndex
,FindIndexBy
First
Group
,GroupBy
Index
,IndexBy
IsArray
IsMatch
Keys
Last
Map
,MapBy
MapMany
,MapManyBy
Object
Order
,OrderBy
Range
Reduce
Reject
,RejectBy
Reverse
,ReverseBy
Select
,SelectBy
SelectMany
,SelectManyBy
Size
Skip
Sort
,SortBy
Take
Uniq
,UniqBy
Value
Values
Where
,WhereBy
Aggregate(memo, fn) IEnumerable
Arguments
iterator
- func(element or value, key or index, memo) memomemo
- anyType
Examples
var res []int
Chain([]int{1, 2}).Aggregate(
func(memo []int, n, _ int) []int {
memo = append(memo, n)
memo = append(memo, n+10)
return memo
},
make([]int, 0),
).Value(&res)
// res = [1 11 2 12]
Same
Reduce
All(predicate) bool
Arguments
predicate
- func(element, index or key) bool
Return
- bool - all the values that pass a truth test
predicate
Examples
ok := Chain([]testModel{
{ID: 1, Name: "one"},
{ID: 1, Name: "two"},
{ID: 1, Name: "three"},
}).All(func(r testModel, _ int) bool {
return r.ID == 1
})
// ok == true
<a name="allBy" />
AllBy(fields) bool
Arguments
fields
- map[string]interface{}
Return
- bool - all the values that pass a truth test
predicate
Examples
ok := Chain([]testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "one"},
{ID: 3, Name: "one"},
}).AllBy(map[string]interface{}{
"name": "one",
})
// ok == true
<a name="any" />
Any(predicate) bool
Arguments
predicate
- func(element or value, index or key) bool
Return
- bool - any of the values that pass a truth test
predicate
Examples
ok := Chain([]testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}).Any(func(r testModel, _ int) bool {
return r.ID == 0
})
// ok == false
<a name="anyBy" />
AnyBy(fields) bool
Arguments
fields
- map[string]interface{}
Return
- bool
Examples
ok := Chain([]testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}).AnyBy(map[string]interface{}{
"name": "two",
})
// ok == true
<a name="chain" />
Chain(source) IEnumerable
Arguments
source
- array or map
Examples
var dst int
Range(1, benchmarkSize, 1).Select(func(r, _ int) int {
return -r
}).Where(func(r, _ int) bool {
return r < -20
}).First().Value(&dst)
// dst = -21
<a name="count" />
Count() int
Examples
src := []string{"a", "b", "c"}
dst := Chain(src).Count()
// dst = 3
Same
Size
Distinct(selector) IEnumerable
Arguments
selector
- nil or func(element or value, index or key) anyType
Examples
src := []int{1, 2, 1, 4, 1, 3}
dst := make([]int, 0)
Chain(src).Distinct(func(n, _ int) (int, error) {
return n % 2, nil
}).Value(&dst)
// dst = [1 2]
Same
Uniq
DistinctBy(fieldName) IEnumerable
Arguments
fieldName
- string
Examples
src := []testModel{
{ID: 1, Name: "a"},
{ID: 2, Name: "a"},
{ID: 3, Name: "a"},
}
dst := make([]testModel, 0)
Chain(src).DistinctBy("name").Value(&dst)
// dst = [{1 a}]
Same
UniqBy
Each(iterator)
Arguments
iterator
- func(element or value, index or key)
Examples
arr := []testModel{
{ID: 1, Name: "one"},
{ID: 1, Name: "two"},
{ID: 1, Name: "three"},
}
Chain(arr).Each(func(r testModel, i int) {
if !(r.ID == arr[i].ID && r.Name == arr[i].Name) {
// wrong
}
})
<a name="field" />
Field(name)
Arguments
name
- field name
Return
- func(interface{}) interface{}
Examples
item := testModel{ 1, "one" }
getAge := Field("age")
_, err := getAge(item)
// err != nil
getName := Field("name")
name, err := getName(item)
// name = "one"
<a name="fieldValue" />
FieldValue(name)
Arguments
name
- field name
Return
- func(interface{}) reflect.Value
Examples
item := testModel{ 1, "one" }
getAgeValue := FieldValue("age")
res := getAgeValue(item)
// res != reflect.Value(nil)
getNameValue := FieldValue("name")
nameValue, err := getNameValue(item)
// nameValue = reflect.ValueOf("one")
<a name="find" />
Find(predicate) IEnumerable
Arguments
predicate
- func(element or value, index or key) bool
Examples
var dst int
Chain([]int{1, 2, 3}).Find(func(r, _ int) bool {
return r == 2
}).Value(&dst)
// dst == 2
// or
var dst int
Chain([][]int{
[]int{1, 3, 5, 7},
[]int{2, 4, 6, 8},
}).Find(func(r []int, _ int) bool {
return r[0]%2 == 0
}).Find(func(r, _ int) bool {
return r > 6
}).Value(&dst)
// dst == 8
<a name="findBy" />
FindBy(fields) IEnumerable
Arguments
fields
- map[string]interface{}
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}
var dst testModel
Chain(src).FindBy(map[string]interface{}{
"id": 2,
}).Value(&dst)
// dst == src[1]
<a name="findIndex" />
FindIndex(predicate) int
Arguments
predicate
- func(element or value, index or key) bool
Return
- int - index
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}
index := Chain(src).FindIndex(func(r testModel, _ int) bool {
return r.Name == src[1].Name
})
// i == 1
<a name="findIndexBy" />
FindIndexBy(fields) int
Arguments
fields
- map[string]interface{}
Return
- int - index
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}
index := Chain(src).FindIndexBy(map[string]interface{}{
"id": 1,
})
// index == 0
<a name="first" />
First() IEnumerable
Arguments
predicate
- func(element or value, index or key) bool
Examples
var dst int
Chain([]int{1, 2, 3}).First().Value(&dst)
// dst == 1
// or
var dst int
Chain([][]int{
[]int{1, 3, 5, 7},
[]int{2, 4, 6, 8},
}).First().First().Value(&dst)
// dst == 1
<a name="group" />
Group(keySelector) IEnumerable
Arguments
keySelector
- func(element or value, index or key) anyType
Examples
dst := make(map[string][]int)
Chain([]int{1, 2, 3, 4, 5}).Group(func(n, _ int) string {
if n%2 == 0 {
return "even"
}
return "odd"
}).Value(&dst)
// dst = map[odd:[1 3 5] even:[2 4]]
<a name="groupBy" />
GroupBy(fieldName) IEnumerable
Arguments
fieldName
- field name
Examples
dst := make(map[string][]testModel)
Chain([]testModel{
{ID: 1, Name: "a"},
{ID: 2, Name: "a"},
{ID: 3, Name: "b"},
{ID: 4, Name: "b"},
}).GroupBy("Name").Value(&dst)
// dst = map[a:[{1 a} {2 a}] b:[{3 b} {4 b}]]
<a name="index" />
Index(indexSelector) IEnumerable
Arguments
indexSelector
- func(element or value, index or key) anyType
Examples
src := []string{"a", "b"}
res := make(map[string]string)
Chain(src).Index(func(item string, _ int) string {
return item
}).Value(&res)
// res = map[a:a b:b]
<a name="indexBy" />
IndexBy(property) IEnumerable
Arguments
property
- string
Examples
arr := []testModel{
{ID: 1, Name: "a"},
{ID: 2, Name: "a"},
{ID: 3, Name: "b"},
{ID: 4, Name: "b"},
}
res := make(map[string]testModel)
Chain(arr).IndexBy("id").Value(&res)
// res = map[1:{{0} 1 a} 2:{{0} 2 a} 3:{{0} 3 b} 4:{{0} 4 b}]
<a name="isArray" />
IsArray(element) bool
Arguments
element
- object
Examples
if !IsArray([]int{}) {
// wrong
}
if IsArray(map[string]int{}) {
// wrong
}
<a name="isMatch" />
IsMatch(element, fields) bool
Arguments
element
- objectfields
- map[string]interface{}
Examples
m := testModel{ 1, "one" }
ok := IsMatch(nil, nil)
// ok = false
ok = IsMatch(m, nil)
// ok = false
ok = IsMatch(m, map[string]interface{}{
"id": m.Id,
"name": "a",
})
// ok = false
ok = IsMatch(m, map[string]interface{}{
"id": m.Id,
"name": m.Name,
})
// ok = true
<a name="keys" />
Keys() IEnumerable
Examples
src := []string{"aa", "bb", "cc"}
dst := make([]int, 0)
Chain(src).Keys().Value(&dst)
// dst = [0 1 2]
src := map[int]string{
1: "a",
2: "b",
3: "c",
4: "d",
}
dst := make([]int, 0)
Chain(src).Keys().Value(&dst)
// dst = [1 2 3 4]
<a name="last" />
Last() IEnumerable
Examples
arr := []int{1, 2, 3}
var res int
chain(arr).Last().Value(&res)
// res = 3
var res []int
src := [][]int{
{1, 2, 3, 4},
{5, 6},
}
Chain(src).Last().Map(func(r, _ int) int {
return r + 5
}).Value(&res)
// res = [10, 11]
<a name="object" />
Object() IEnumerable
Examples
src := [][]interface{}{
[]interface{}{"a", 1},
[]interface{}{"b", 2},
}
dst := make(map[string]int)
Chain(src).Object().Value(&dst)
// dst = map[a:1 b:2]
<a name="order" />
Order(selector) IEnumerable
Arguments
selector
- func(element, key or index) anyType
Examples
arr := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(arr).Order(func(n testModel, _ int) int {
return n.ID
}).Value(&res)
// res = [{{0} 1 one} {{0} 2 two} {{0} 3 three}]
Same
Sort
OrderBy(fieldName) IEnumerable
Arguments
fieldName
- string
Examples
arr := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(arr).OrderBy("id").Value(&res)
// res = [{{0} 1 one} {{0} 2 two} {{0} 3 three}]
Same
SortBy
Range(start, stop, step) IEnumerable
Arguments
start
- intstop
- intstep
- int
Examples
var res []int
Range2(0, 0, 1).Value(&res)
// res = []
var res []int
Range2(0, 10, 0).Value(&res)
// panic
var res []int
Range2(4, 0, -1).Value(&res)
// res = [4 3 2 1]
var res []int
Range2(0, 2, 1).Value(&res)
// res = [0 1]
var res []int
Range2(0, 3, 2).Value(&res)
// res = [0 2]
<a name="reject" />
Reject(predicate) IEnumerable
Arguments
predicate
- func(element or value, index or key) bool
Examples
arr := []int{1, 2, 3, 4}
var res []int
Chain(arr).Reject(func(n, i int) bool {
return n%2 == 0
}).Value(&res)
// res = [1, 3]
Same
Except
RejectBy(fields) IEnumerable
Arguments
fields
- map[string]interface{}
Examples
arr := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(arr).RejectBy(map[string]interface{}{
"Id": 1,
}).Value(&res)
// res = []testModel{ {ID: 2, Name: "two"}, {ID: 3, Name: "three"} }
Same
ExceptBy
Reverse(selector) IEnumerable
Arguments
selector
- func(element, index or key) anyType
Examples
src := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(src).Reverse(func(r testModel, _ int) int {
return r.ID
}).Value(&res)
// res = []testModel{ {ID: 3, Name: "three"}, {ID: 2, Name: "two"}, {ID: 1, Name: "one"} }
<a name="reverseBy" />
ReverseBy(fieldName) IEnumerable
Arguments
fieldName
- string
Examples
src := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(src).ReverseBy("id").Value(&res)
// res = []testModel{ {ID: 3, Name: "three"}, {ID: 2, Name: "two"}, {ID: 1, Name: "one"} }
<a name="select" />
Select(selector) IEnumerable
Arguments
selector
- func(element, index or key) anyType
Examples
src := []string{"11", "12", "13"}
dst := make([]int, 0)
Chain(src).Select(func(s string, _ int) int {
n, _ := strconv.Atoi(s)
return n
}).Value(&dst)
// dst = [11 12 13]
Same
Map
SelectBy(fieldName) IEnumerable
Arguments
fieldName
- string
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}
dst := make([]string, 0)
Chain(src).SelectBy("name").Value(&dst)
// dst = [one two three]
Same
MapBy
SelectMany(selector) IEnumerable
Arguments
selector
- func(element, index or key) anyType with array or slice
Examples
src := [2]int{1, 2}
var dst []int
Chain(src).SelectMany(func(r, _ int) []int {
return []int{r - 1, r + 1}
}).Value(&dst)
// dst = [0 2 1 3]
Same
MapMany
SelectManyBy(property) IEnumerable
Arguments
property
- string
Examples
src := []testSelectManyModel{
{Array: [2]int{1, 2}},
{Array: [2]int{3, 4}},
}
var dst []int
Chain(src).SelectManyBy("Array").Value(&dst)
// res = [1 2 3 4]
Same
MapManyBy
Skip(count) IEnumerable
Arguments
count
- int
Examples
src := []int{1, 2, 3}
dst := make([]int, 0)
Chain(src).Skip(2).Value(&dst)
// dst = [3]
<a name="take" />
Take(count) IEnumerable
Arguments
count
- int
Examples
src := []int{1, 2, 3}
dst := make([]int, 0)
Chain(src).Take(1).Value(&dst)
// res = [1]
<a name="value" />
Value(res interface{})
Arguments
res
- array or slice or reflect.Value(array) or reflect.Value(map)
Examples
resValue := reflect.New(
reflect.SliceOf(
reflect.TypeOf(1),
),
)
Chain([]string{"a", "b"}).Map(func(_ string, i int) int {
return i
}).Value(resValue)
// resValue = &[0 1]
src := []testModel{
{ID: 1, Name: "a"},
{ID: 2, Name: "a"},
{ID: 3, Name: "b"},
{ID: 4, Name: "b"},
}
resValue := reflect.New(
reflect.MapOf(
reflect.TypeOf(src[0].Name),
reflect.TypeOf(src),
),
)
Chain(src).GroupBy("name").Value(resValue)
// res = &map[even:[2 4] odd:[1 3 5]]
<a name="values" />
Values() IEnumerable
Examples
src := []string{"a", "b"}
dst := make([]string, 0)
Chain(src).Values().Value(&dst)
// dst = [a b]
src := map[int]string{
1: "a",
2: "b",
3: "c",
4: "d",
}
dst := make([]string, 0)
Chain(src).Values().Value(&dst)
// dst = [a b c d]
<a name="where" />
Where(predicate) IEnumerable
Arguments
predicate
- func(element or value, index or key) bool
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "one"},
{ID: 3, Name: "three"},
{ID: 4, Name: "three"},
}
dst := make([]testModel, 0)
Chain(src).Where(func(r testModel, _ int) bool {
return r.ID%2 == 0
}).Value(&dst)
// len(dst) == 2 && dst[0] == src[1] && dst[1] == src[3])
Same
Filter
WhereBy(fields) IEnumerable
Arguments
fields
- map[string]interface{}
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "one"},
{ID: 3, Name: "three"},
{ID: 4, Name: "three"},
}
dst := make([]testModel, 0)
Chain(src).WhereBy(map[string]interface{}{
"Name": "one",
}).Value(&dst)
// len(dst) == 2 && dst[0] == src[0] && dst[1] == src[1]
Same
FilterBy
Release Notes
v2.1.0 (2020-11-17)
* IEnumerable增加Order、OrderBy、Sort、SortBy
* IEnumerable.Aggregate(memo interface{}, fn interface{}) -> IEnumerable.Aggregate(fn interface{}, memo interface{})
v2.0.0 (2019-06-27)
* 删除IQuery
* IEnumerable增加MapMany、MapManyBy、SelectMany、SelectManyBy
v1.6.0 (2019-06-21)
* IEnumerable增加Count、Size
* 删除FindLastIndex
v1.5.0 (2019-06-18)
* 增加Chain Benchmark
* IEnumerable增加Group、GroupBy
* 优化IEnumerable的Distinct、Enumerator、Index、Property、Select、Where
v1.4.0 (2019-06-15)
* Reduce、Take支持IEnumerable
* IEnumerable增加Aggregate、Skip
* IQuery删除Clone
* 优化IEnumerable的First、Index、Values
v1.3.0 (2019-06-09)
* FindIndex、FindIndexBy、Keys、Map、MapBy、Object、Uniq、UniqBy、Values支持IEnumerable
* IEnumerable增加Distinct、DistinctBy、Select、SelectBy
v1.2.0 (2019-06-04)
* Each、Filter、Where支持IEnumerable
v1.1.0 (2019-06-02)
* 增加IEnumerable、IEnumerator
* All、Any、Chain、Find、First、Range2、Value支持IEnumerable
v1.0.0 (2019-04-23)
* first edition