注:以下所有的方法来自于 https://github.com/ahmetb/go-linq,只对对应方法进行用法分析.
具体的使用示例可以参考 https://godoc.org/github.com/ahmetb/go-linq#
目录
Ⅰ.前置:结构体与数据构造方法
type Book struct {
Name string
Author string
Money float64
WordsNum int
PublishTime time.Time
}
type Person struct {
Name string //拥有者的名字
}
type Pet struct {
Name string //动物的名字
OwnerName string //拥有者的名字
}
type Man struct {
Name string //拥有者的名字
Pets []Pets //宠物们
}
type Pets struct {
Name string //动物的名字
}
func MakeInnerData() []Man {
man := make([]Man, 0)
man = append(man, Man{
Name: "康康",
Pets: []Pets{
{Name: "康康的狗"}, {Name: "康康的猫"}},
})
man = append(man, Man{
Name: "老施",
Pets: []Pets{
{Name: "老施的🐟"}, {Name: "老施的鸟"}},
})
man = append(man, Man{
Name: "小明",
Pets: []Pets{
{Name: "小明的🐖"}, {Name: "小明的狗"}},
})
return man
}
func MakeJoinData() ([]Person, []Pet) {
kangkang := Person{Name: "爱吃合合乐的康康"}
laoshi := Person{Name: "老施"}
xiaoming := Person{Name: "不要催-小明"}
expect := Person{Name: "我是没有宠物的人"}
dog := Pet{Name: "康康的狗", OwnerName: kangkang.Name}
cat := Pet{Name: "康康的猫", OwnerName: kangkang.Name}
fish := Pet{Name: "老施的🐟", OwnerName: laoshi.Name}
pig := Pet{Name: "小明的🐖", OwnerName: xiaoming.Name}
return []Person{kangkang, laoshi, xiaoming, expect}, []Pet{dog, cat, fish, pig}
}
func MakeBook() []Book {
bookList := make([]Book, 0)
bookList = append(bookList, Book{
Name: "Go语言",
Author: "Go",
Money: 100,
WordsNum: 1000,
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "Effective Java",
Author: "Java",
Money: 78,
WordsNum: 9000,
PublishTime: time.Date(2020, 2, 15, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "Java语言",
Author: "Java",
Money: 50,
WordsNum: 3000,
PublishTime: time.Date(2020, 2, 1, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "Lua语言",
Author: "Lua",
Money: 75,
WordsNum: 45000,
PublishTime: time.Date(2020, 1, 10, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "React语言",
Author: "React",
Money: 99,
WordsNum: 14500,
PublishTime: time.Date(2020, 7, 1, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "Red语言",
Author: "Red",
Money: 28,
WordsNum: 880,
PublishTime: time.Date(2019, 4, 1, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "JavaScript语言",
Author: "JavaScript",
Money: 81,
WordsNum: 3776,
PublishTime: time.Date(2019, 5, 17, 10, 0, 0, 0, time.Local),
})
return bookList
}
func MakeBook1() []Book {
bookList := make([]Book, 0)
bookList = append(bookList, Book{
Name: "Go语言",
Author: "Go",
Money: 100,
WordsNum: 1000,
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "Effective Java",
Author: "Java",
Money: 78,
WordsNum: 9000,
PublishTime: time.Date(2020, 2, 15, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "Go语言(第二版)",
Author: "Go",
Money: 50,
WordsNum: 3000,
PublishTime: time.Date(2020, 2, 1, 10, 0, 0, 0, time.Local),
})
return bookList
}
func MakeBook2() []Book {
bookList := make([]Book, 0)
bookList = append(bookList, Book{
Name: "Go语言",
Author: "Go",
Money: 100,
WordsNum: 1000,
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
})
return bookList
}
func MakeBook3() []Book {
bookList := make([]Book, 0)
bookList = append(bookList, Book{
Name: "Go语言",
Author: "Go",
Money: 100,
WordsNum: 1000,
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
})
bookList = append(bookList, Book{
Name: "Go语言(第三版)",
Author: "Go",
Money: 50,
WordsNum: 3000,
PublishTime: time.Date(2020, 2, 1, 10, 0, 0, 0, time.Local),
})
return bookList
}
Ⅱ.方法使用解析
1、Aggregate:自定义聚合操作
自定义聚合方法,提供了两个变式,一个是支持固定类型的 AggregateT 方法,一个是支持interface的 Aggregate 方法。
Aggregate提供了一个方法,支持前后两个参数:
func (q Query) Aggregate(f func(interface{}, interface{}) interface{}) interface{}
该方法就是聚合操作的具体方法,这边的使用例子如下:
func Aggregate() {
bookList := MakeBook()
query := linq.From(bookList)
// 这边的聚合操作其实就是【自定义对应的比较方法】。
// 根据注释,第一次拿到的是数组的第一个元素,然后跟第二个元素进行比较,如果第二个元素符合条件则【替换第一个元素】,否则当前聚合操作还是持有第一个元素。
// 以此类推后面的元素
result := query.Aggregate(AggregateFunc).(Book)
fmt.Println(fmt.Sprintf("聚合操作查询出的结果是【%s】这本书,它的发布时间最早为:%v", result.Name, timed.GetTimeDefaultFormatString(result.PublishTime.Unix())))
}
//自定义聚合操作方法
var AggregateFunc = func(first interface{}, second interface{}) interface{} {
if first.(Book).PublishTime.Before(second.(Book).PublishTime) {
return first
}
return second
}
AggregateT 方法支持一个自定义类型的入参,如下:
// AggregateT is the typed version of Aggregate.
//
// - f is of type: func(TSource, TSource) TSource
//
// NOTE: Aggregate has better performance than AggregateT.
func (q Query) AggregateT(f interface{}) interface{}
类似的除了方法自定义之外,这边也是支持两个入参,具体使用例子类似上面
2、All:判断是否所有元素都满足条件
All提供两个方法
一个是支持具体类型的 AllT 方法,
一个是支持interface的All方法,入参是一个predicate的条件方法,即返回是否所有元素都满足条件的结果,true或者false
// All determines whether all elements of a collection satisfy a condition.
func (q Query) All(predicate func(interface{}) bool) bool
这边的使用例子是:
func All() {
bookList := MakeBook()
query := linq.From(bookList)
result := query.All(