/\ \
__ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ __ ___
/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ /'_ `\ / __`\
\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ /\ \L\ \/\ \L\ \
\ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\\ \____ \ \____/
\/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_/ \/___L\ \/___/
/\____/
\_/__/
Underscore.go
like underscore.js and C# LINQ, but for Go
Installation
$ go get github.com/ahl5esoft/golang-underscore
Update
$ go get -u github.com/ahl5esoft/golang-underscore
Lack
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) memo
memo
- 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
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
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
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
AnyBy(fields) bool
Arguments
fields
- map[string]interface{}
Return
Examples
ok := Chain([]testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}).AnyBy(map[string]interface{}{
"name": "two",
})
// ok == true
Chain(source) IEnumerable
Arguments
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
Count() int
Examples
src := []string{"a", "b", "c"}
dst := Chain(src).Count()
// dst = 3
Same
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
DistinctBy(fieldName) IEnumerable
Arguments
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
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
}
})
Field(name)
Arguments
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"
FieldValue(name)
Arguments
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")
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
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]
FindIndex(predicate) int
Arguments
predicate
- func(element or value, index or key) bool
Return
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
FindIndexBy(fields) int
Arguments
fields
- map[string]interface{}
Return
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
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
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]]
GroupBy(fieldName) IEnumerable
Arguments
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}]]
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]
IndexBy(property) IEnumerable
Arguments
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}]
IsArray(element) bool
Arguments
Examples
if !IsArray([]int{}) {
// wrong
}
if IsArray(map[string]int{}) {
// wrong
}
IsMatch(element, fields) bool
Arguments
element
- object
fields
- 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
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]
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]
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]
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
OrderBy(fieldName) IEnumerable
Arguments
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
Range(start, stop, step) IEnumerable
Arguments
start
- int
stop
- int
step
- 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]
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
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
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"} }
ReverseBy(fieldName) IEnumerable
Arguments
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"} }
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
SelectBy(fieldName) IEnumerable
Arguments
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
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
SelectManyBy(property) IEnumerable
Arguments
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
Skip(count) IEnumerable
Arguments
Examples
src := []int{1, 2, 3}
dst := make([]int, 0)
Chain(src).Skip(2).Value(&dst)
// dst = [3]
Take(count) IEnumerable
Arguments
Examples
src := []int{1, 2, 3}
dst := make([]int, 0)
Chain(src).Take(1).Value(&dst)
// res = [1]
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]]
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]
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
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
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