/\ \
__ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ __ ___
/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ /'_ `\ / __`\
\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ /\ \L\ \/\ \L\ \
\ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\\ \____ \ \____/
\/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_/ \/___L\ \/___/
/\____/
\_/__/
Underscore.go

like underscore.js, but for Go
Installation
$ go get github.com/ahl5esoft/golang-underscore
Update
$ go get -u github.com/ahl5esoft/golang-underscore
Lack
- IQuery性能差,将来会逐步用IEnumerable替代
Documentation
API
Aggregate
All, AllBy
Any, AnyBy
AsParallel
Chain
Distinct, DistinctBy
Each
Filter, FilterBy
Find, FindBy
FindIndex, FindIndexBy
First
Group, GroupBy
Index, IndexBy
IsArray
IsMatch
Keys
Last
Map, MapBy
MapMany, MapManyBy
Object
Property, PropertyRV
Range
Reduce
Reject, RejectBy
Reverse, ReverseBy
Select, SelectBy
Size
Skip
Sort, SortBy
Take
Uniq, UniqBy
Values
Where, WhereBy
Aggregate(memo, fn) IEnumerable
Aggregate(source, iterator) IQuery
Arguments
memo - anyType
iterator - func(memo, element or value, key or index) memo
Examples
dst := make([]int, 0)
Chain2([]int{1, 2}).Aggregate(make([]int, 0), func(memo []int, n, _ int) []int {
memo = append(memo, n)
memo = append(memo, n+10)
return memo
}).Value(&dst)
// dst = [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 := Chain2([]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(properties) bool
Arguments
properties - map[string]interface{}
Return
- bool - all the values that pass a truth test
predicate
Examples
ok := Chain2([]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 := Chain2([]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(properties) bool
Arguments
properties - map[string]interface{}
Return
Examples
ok := Chain2([]testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}).AnyBy(map[string]interface{}{
"name": "two",
})
// ok == true
Chain(source).AsParallel()...
Support
Examples
arr := []int{ 1, 2, 3 }
Chain(arr).AsParallel().Each(func (n, i int) {
// code
})
Chain(source)
Arguments
Return
- IQuery - a wrapped object, wrapped objects until value is called
Examples
res := make(map[string][]int)
Chain([]int{1, 2, 1, 4, 1, 3}).Uniq(nil).Group(func(n, _ int) string {
if n%2 == 0 {
return "even"
}
return "old"
}).Value(&res)
// len(res) == 2 && ok == true
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)
Chain2(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)
Chain2(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"},
}
Chain2(arr).Each(func(r testModel, i int) {
if !(r.ID == arr[i].ID && r.Name == arr[i].Name) {
// wrong
}
})
Find(predicate) IQuery
Find(predicate) IEnumerable
Arguments
predicate - func(element or value, index or key) bool
Examples
var dst int
Chain2([]int{1, 2, 3}).Find(func(r, _ int) bool {
return r == 2
}).Value(&dst)
// dst == 2
// or
var dst int
Chain2([][]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(properties) IQuery
FindBy(properties) IEnumerable
Arguments
properties - map[string]interface{}
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}
var dst testModel
Chain2(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 := Chain2(src).FindIndex(func(r testModel, _ int) bool {
return r.Name == src[1].Name
})
// i == 1
FindIndexBy(properties) int
Arguments
properties - map[string]interface{}
Return
Examples
src := []testModel{
{ID: 1, Name: "one"},
{ID: 2, Name: "two"},
{ID: 3, Name: "three"},
}
index := Chain2(src).FindIndexBy(map[string]interface{}{
"id": 1,
})
// index == 0
First() IQuery
First() IEnumerable
Arguments
predicate - func(element or value, index or key) bool
Examples
var dst int
Chain2([]int{1, 2, 3}).First().Value(&dst)
// dst == 1
// or
var dst int
Chain2([][]int{
[]int{1, 3, 5, 7},
[]int{2, 4, 6, 8},
}).First().First().Value(&dst)
// dst == 1
Group(source, keySelector)
Arguments
source - array or map
keySelector - func(element or value, index or key) anyType
Return
- interface{} - map[anyType][](element or value)
Examples
src := []int{ 1, 2, 3, 4, 5 }
var res map[string][]int
Chain(src).Group(func (n, _ int) string {
if n % 2 == 0 {
return "even"
}
return "odd"
}).Value(&res)
// or
res := Group(src, func (n, _ int) string {
if n % 2 == 0 {
return "even"
}
return "odd"
}).(map[string][]int)
// res = map[odd:[1 3 5] even:[2 4]]
GroupBy(source, property)
Arguments
source - array or map
property - property name
Return
- interface{} - map[property type][](element or value)
Examples
arr := []testModel{
{ID: 1, Name: "a"},
{ID: 2, Name: "a"},
{ID: 3, Name: "b"},
{ID: 4, Name: "b"},
}
var res map[string][]testModel
Chain(arr).GroupBy("name").Value(&res)
// or
res := GroupBy(arr, "name").(map[string][]testModel)
// res = map[a:[{{0} 1 a} {{0} 2 a}] b:[{{0} 3 b} {{0} 4 b}]]
Index(source, indexSelector)
Arguments
source - array or map
indexSelector - func(element or value, index or key) anyType
Return
- interface{} - map[anyType](element or value)
Examples
src := []string{ "a", "b" }
var res map[string]string
Chain(src).Index(func (r string, _ int) string {
return r
}).Value(&res)
// or
res := Index(src, func (r string, _ int) string {
return r
}).(map[string]string)
// res = map[a:a b:b]
IndexBy(source, property)
Arguments
source - array or map
property - string
Return
- interface{} - map[propertyType](element or value)
Examples
arr := []testModel{
{ID: 1, Name: "a"},
{ID: 2, Name: "a"},
{ID: 3, Name: "b"},
{ID: 4, Name: "b"},
}
var res map[int]testModel
Chain(arr).IndexBy("id").Value(&res)
// or
res := IndexBy(arr, "id").(map[int]testModel)
// res = map[1:{{0} 1 a} 2:{{0} 2 a} 3:{{0} 3 b} 4:{{0} 4 b}]
IsArray(element)
Arguments
Return
Examples
if !IsArray([]int{}) {
// wrong
}
if IsArray(map[string]int{}) {
// wrong
}
IsMatch(element, properties)
Arguments
element - object
properties - map[string]interface{}
Return
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
Keys() IQuery
Arguments
Examples
src := []string{"aa", "bb", "cc"}
dst := make([]int, 0)
Chain2(src).Keys().Value(&dst)
// dst = [0 1 2]
src := map[int]string{
1: "a",
2: "b",
3: "c",
4: "d",
}
dst := make([]int, 0)
Chain2(src).Keys().Value(&dst)
// dst = [1 2 3 4]
Last(source)
Arguments
Return
- interface{} - last element of
source
Examples
arr := []int{1, 2, 3}
var res int
chain(arr).Last().Value(&res)
// or
res := Last(arr).(int)
// res = 3
dict := map[string]string{
"a": "aa",
"b": "bb",
}
var str string
Chain(dict).Last().Value(&str)
// or
str := Last(dict).(string)
// res = "aa" or "bb"
MapMany(source, selector)
Arguments
source - array or map
selector - func(element, index or key) anyType with array or slice
Return
- interface{} - an slice of property elem value
Examples
src := []int{1, 2}
MapMany(src, func(r, _ int) int {
return r // will panic because `r` is not array or slice
})
// or
Chain(src).MapMany(func(r, _ int) int {
return r // will panic because `r` is not array or slice
})
var res []int
Chain(src).MapMany(func(r, _ int) []int {
var temp []int
Range(0, r, 1).Map(func(_, _ int) int {
return r
}).Value(&temp)
return temp
}).Value(&res)
// or
res := MapMany(src, func(r, _ int) []int {
var temp []int
Range(0, r, 1).Map(func(_, _ int) int {
return r
}).Value(&temp)
return temp
}).([]int)
// res = [1 2 2]
MapManyBy(source, property)
Arguments
source - array
property - string
Return
- interface{} - an slice of propery elem value
Examples
src := []mapManyTestModel{
{Slice: []string{"a", "b"}},
{Slice: []string{"c", "d"}},
}
Chain(src).MapManyBy("Str") // will panic because `Str` property value is not array or slice
// or
MapManyBy(src, "Str") // will panic because `Str` property value is not array or slice
var res []string
Chain(src).MapManyBy("Slice").Value(&res)
// or
res := MapManyBy(src, "Slice").([]string)
// res = [a b c d]
Object() IEnumerable
Examples
src := [][]interface{}{
[]interface{}{"a", 1},
[]interface{}{"b", 2},
}
dst := make(map[string]int)
Chain2(src).Object().Value(&dst)
// dst = map[a:1 b:2]
Property(name)
Arguments
Return
- func(interface{}) (interface{}, error)
Examples
item := testModel{ 1, "one" }
getAge := Property("age")
_, err := getAge(item)
// err != nil
getName := Property("name")
name, err := getName(item)
// name = "one"
Property(name)
Arguments
Return
- func(interface{}) (reflect.Value, error)
Examples
item := testModel{ 1, "one" }
getAgeRV := PropertyRV("age")
_, err := getAgeRV(item)
// err != nil
getNameRV := PropertyRV("name")
nameRV, err := getNameRV(item)
// nameRV = reflect.ValueOf("one")
Range(start, stop, step) IQuery
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(source, predicate)
Arguments
source - array or map
predicate - func(element or value, index or key) bool
Return
- interface{} - an array of all the values that without pass a truth test
predicate
Examples
arr := []int{1, 2, 3, 4}
var res []int
Chain(arr).Reject(func(n, i int) bool {
return n%2 == 0
}).Value(&res)
// or
res := Reject(arr, func(n, i int) bool {
return n%2 == 0
}).([]int)
// res = [1 3]
RejectBy(source, properties)
Arguments
source - array or map
properties - map[string]interface{}
Return
- interface{} - an array of all the values that without pass a truth test
properties
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)
// or
res := RejectBy(arr, map[string]interface{}{
"Id": 1,
}).([]testModel)
// res = [{{0} 2 two} {{0} 3 three}]
Reverse(source, selector)
Arguments
source - array or map
selector - func(element, key or index) anyType
Return
- interface{} - an array of
source that reversed
Examples
arr := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(arr).Reverse(func(n testModel, _ int) int {
return n.ID
}).Value(&res)
// or
res := Reverse(arr, func(n testModel, _ int) int {
return n.ID
}).([]testModel)
// res = [{{0} 3 three} {{0} 2 two} {{0} 1 one}]
ReverseBy(source, selector)
Arguments
source - array or map
property - string
Return
- interface{} - an array of
source that reversed
Examples
arr := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(arr).ReverseBy("id").Value(&res)
// or
res := ReverseBy(arr, "id").([]testModel)
// res = [{{0} 3 three} {{0} 2 two} {{0} 1 one}]
Select(selector) IEnumerable
Arguments
selector - func(element, index or key) anyType
Examples
src := []string{"11", "12", "13"}
dst := make([]int, 0)
Chain2(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)
Chain2(src).SelectBy("name").Value(&dst)
// dst = [one two three]
Same
Size(source)
Arguments
Return
Examples
dict := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
l := Size(dict)
// l = 3
Skip(count) IEnumerable
Arguments
Examples
src := []int{1, 2, 3}
dst := make([]int, 0)
Chain2(src).Skip(2).Value(&dst)
// dst = [3]
Sort(source, selector)
Arguments
source - array or map
selector - func(element, key or index) anyType
Return
- interface{} - an array of
source that sorted
Examples
arr := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(arr).Sort(func(n testModel, _ int) int {
return n.ID
}).Value(&res)
// or
res := Sort(arr, func(n testModel, _ int) int {
return n.ID
}).([]testModel)
// res = [{{0} 1 one} {{0} 2 two} {{0} 3 three}]
SortBy(source, property)
Arguments
source - array or map
property - string
Return
Examples
arr := []testModel{
{ID: 2, Name: "two"},
{ID: 1, Name: "one"},
{ID: 3, Name: "three"},
}
var res []testModel
Chain(arr).SortBy("id").Value(&res)
// or
res := SortBy(arr, "id").([]testModel)
// res = [{{0} 1 one} {{0} 2 two} {{0} 3 three}]
Take(count) IEnumerable
Take(count) IQuery
Arguments
Examples
src := []int{1, 2, 3}
dst := make([]int, 0)
Chain2(src).Take(1).Value(&dst)
// res = [1]
Values() IEnumerable
Values() IQuery
Examples
src := []string{"a", "b"}
dst := make([]string, 0)
Chain2(src).Values().Value(&dst)
// dst = [a b]
src := map[int]string{
1: "a",
2: "b",
3: "c",
4: "d",
}
dst := make([]string, 0)
Chain2(src).Values().Value(&dst)
// dst = [a b c d]
Where(predicate) IEnumerable
Where(predicate) IQuery
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)
Chain2(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(properties) IEnumerable
WhereBy(properties) IQuery
Arguments
properties - 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)
Chain2(src).WhereBy(map[string]interface{}{
"Name": "one",
}).Value(&dst)
// len(dst) == 2 && dst[0] == src[0] && dst[1] == src[1]
Same
Release Notes
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、Chain2、Find、First、Range2、Value支持IEnumerable
v1.0.0 (2019-04-23)
* first edition