feat(Go-Tool):2020/11/25:完善linq包使用示例

This commit is contained in:
Huangzj
2020-11-25 14:08:56 +08:00
parent 333d7a5d66
commit 591aaa299a
5 changed files with 525 additions and 39 deletions
+2
View File
@@ -60,6 +60,8 @@
2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组) 2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组)
2020/11/25:完善linq包使用示例
# mod vendor模式加载包 # mod vendor模式加载包
通过go mod的方式加载的github上面的包会有报红的问题,但是包本身是可以运行的,这样就是会有一个问题,如果你想要点击去看方法的内容,没办法做到 通过go mod的方式加载的github上面的包会有报红的问题,但是包本身是可以运行的,这样就是会有一个问题,如果你想要点击去看方法的内容,没办法做到
+56
View File
@@ -69,3 +69,59 @@ func MakeBook() []Book {
}) })
return bookList 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
}
+57
View File
@@ -0,0 +1,57 @@
/*
* @Author : huangzj
* @Time : 2020/11/24 16:17
* @Description
*/
package linqUse
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}
}
+2 -2
View File
@@ -10,7 +10,7 @@ import "time"
//书籍发布时间是否早于--.--.-- //书籍发布时间是否早于--.--.--
var PublishTimeBeforeFunc = func(thisBook interface{}) bool { var PublishTimeBeforeFunc = func(thisBook interface{}) bool {
if thisBook.(Book).PublishTime.Before(time.Date(2020, 1, 1, 0, 0, 0, 0, time.Local)) { if thisBook.(Book).PublishTime.Before(time.Date(2019, 1, 1, 0, 0, 0, 0, time.Local)) {
return true return true
} }
return false return false
@@ -34,7 +34,7 @@ var PublishTimeAfterFunc2 = func(thisBook interface{}) bool {
//自定义聚合操作方法 //自定义聚合操作方法
var AggregateFunc = func(first interface{}, second interface{}) interface{} { var AggregateFunc = func(first interface{}, second interface{}) interface{} {
if first.(Book).PublishTime.Before(second.(*Book).PublishTime) { if first.(Book).PublishTime.Before(second.(Book).PublishTime) {
return first return first
} }
return second return second
+408 -37
View File
@@ -3,6 +3,8 @@
* @Time : 2020/11/12 10:52 * @Time : 2020/11/12 10:52
* @Description:这边是linq包的使用操作,为之后的使用做一些示例 * @Description:这边是linq包的使用操作,为之后的使用做一些示例
* 包引用命令: go get github.com/ahmetalpbalkan/go-linq * 包引用命令: go get github.com/ahmetalpbalkan/go-linq
* 示例参考地址:https://godoc.org/github.com/ahmetb/go-linq#
* 在Idea中对应方法名上使用 Shift+F1 组合键操作可以直接跳转到方法对应的地址
*/ */
package linqUse package linqUse
@@ -10,59 +12,422 @@ package linqUse
import ( import (
"Go-Tool/util/timed" "Go-Tool/util/timed"
"fmt" "fmt"
"github.com/ahmetalpbalkan/go-linq" "github.com/ahmetb/go-linq"
"strconv"
"testing" "testing"
"time" "time"
) )
func Test(t *testing.T) { func Test(t *testing.T) {
bookList := MakeBook()
query := linq.From(bookList)
//Aggregate(query) //自定义聚合操作 //Aggregate() //自定义聚合操作
//
//All(query) //判断数组的所有元素是否都满足条件 //All() //判断数组的所有元素是否都满足条件
//
//AnyWith(query) //判断数组是否有任意个元素满足条件 //AnyWith() //判断数组是否有任意个元素满足条件
//Calculate() //这个方法只能计算数值类型 //Calculate() //这个方法只能计算数值类型
//Combine(query) //组合两个数组的两种方式 //Combine() //组合两个数组的两种方式
//Distinct() //返回数组中唯一的元素
//Except() //返回第一个序列没有出现在第二个序列中的成员
//GroupBy() //按照对应规则进行分组
//Intersect() //产生两个数组的交集
//Join() //对两个有关联的数据进行处理
//OrderBy() //排序
//Select() //筛选结构体中对应的元素
//SelectMany() //对多维数组进行合并或者其他处理 对结构体中的数组进行处理(与结构体结合操作)
//Skip() //略过指定条件的元素
//Count() //计算数组总长度
//Result() //对结果集进行操作
Take() //获取对应数量的元素,一般多用在排序后前几个的元素
}
func Take() {
bookList := MakeBook()
query := linq.From(bookList)
query.OrderByDescendingT(func(book Book) string {
return book.Author
}).Take(3).ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
})
fmt.Println()
fmt.Println()
//超出对应数量的元素会不会报错(输出所有的元素)
query.OrderByDescendingT(func(book Book) string {
return book.Author
}).Take(100).ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
})
fmt.Println()
fmt.Println()
//负数会发生什么情况(直接返回,不做操作)
query.OrderByDescendingT(func(book Book) string {
return book.Author
}).Take(-2).ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
})
}
func Result() {
bookList := MakeBook()
query := linq.From(bookList)
bookMap := make(map[string]string, 0)
query.SelectT(func(book Book) linq.KeyValue {
return linq.KeyValue{
Key: book.Author,
Value: book.Name,
}
}).ToMap(&bookMap)
for key, value := range bookMap {
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", key, value))
}
fmt.Println()
fmt.Println()
//如果key相同的话,前面的元素会被覆盖掉(只会保留最后一个)
bookList1 := MakeBook1()
query1 := linq.From(bookList1)
bookMap1 := make(map[string]string, 0)
query1.SelectT(func(book Book) linq.KeyValue {
return linq.KeyValue{
Key: book.Author,
Value: book.Name,
}
}).ToMap(&bookMap1)
for key, value := range bookMap1 {
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", key, value))
}
fmt.Println()
fmt.Println()
bookList2 := MakeBook()
query2 := linq.From(bookList2)
bookMap2 := make(map[string]Book, 0)
query2.ToMapByT(&bookMap2,
//这个方法决定key的字段是什么
func(book Book) string {
return book.Author
}, //这个方法决定value的字段是什么
func(book Book) Book {
return book
})
for key, value := range bookMap2 {
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", key, value.Name))
}
}
func Count() {
bookList := MakeBook()
query := linq.From(bookList)
fmt.Println(fmt.Sprintf("数组中发布时间早于2019-1-1的书有%d本", query.CountWithT(PublishTimeBeforeFunc)))
fmt.Println(fmt.Sprintf("数组中发布时间晚于2018-1-1的书有%d本", query.CountWithT(PublishTimeAfterFunc)))
}
func Skip() {
bookList := MakeBook()
query := linq.From(bookList)
fmt.Println(fmt.Sprintf("跳过三个元素,返回的数组中包含%d个元素", len(query.Skip(3).Results()))) fmt.Println(fmt.Sprintf("跳过三个元素,返回的数组中包含%d个元素", len(query.Skip(3).Results())))
fmt.Println(fmt.Sprintf("跳过发布时间在2020.1.1之的元素,返回的数组中包含%d个元素", len(query.SkipWhile(PublishTimeBeforeFunc).Results()))) //这个方法好像有问题,没办法过滤 fmt.Println(fmt.Sprintf("跳过发布时间在2018.1.1之的元素,返回的数组中包含%d个元素", query.SkipWhile(PublishTimeAfterFunc).Count()))
author := make([]string, 0) }
query.Select(func(book interface{}) interface{} {
return book.(Book).Author
}).ToSlice(&author)
fmt.Println(author)
query1 := linq.From([][]Book{bookList, bookList})
query1.SelectMany(func(query interface{}) linq.Query {
fmt.Println(query)
return linq.From(query)
}).Select(func(book interface{}) interface{} {
return book.(Book).Author
}).ToSlice(&author)
fmt.Println(author)
//Contains(query) //判断数组中是否包含某个元素 func SelectMany() {
//query.CountWith() input := [][]int{{1, 2, 3}, {4, 5, 6, 7}}
//
//query.Distinct()
//query.DistinctBy()
//
//query.OrderBy()
//query.OrderByDescending()
//FirstAndLast(query) //获取第一个/最后一个元素 //二位数组进行合并
linq.From(input).SelectManyT(
func(i []int) linq.Query {
return linq.From(i)
},
).ForEachT(func(num int) {
fmt.Println(num)
})
fmt.Println()
fmt.Println()
//三维数组进行合并
input1 := [][][]int{{{1, 2, 3}}, {{4, 5, 6, 7}, {8, 9, 10}}}
linq.From(input1).SelectManyT(
func(i [][]int) linq.Query {
return linq.From(i)
},
).SelectManyT(
func(i []int) linq.Query {
return linq.From(i)
},
).ForEachT(func(num int) {
fmt.Print(num)
fmt.Print(" ")
})
//SelectMany的主要作用是,结构体中包含数组元素,可以把数组元素取出来和结构体做相应的操作
//如果是结构体中有多个数组的操作,可以把对应的多个数组放到一个新定义的结构体数组中
fmt.Println()
men := MakeInnerData()
linq.From(men).
//第一个方法筛选出结构体对应的数组
SelectManyByT(func(man Man) linq.Query {
return linq.From(man.Pets)
},
//第二个方法这边可以拿到数组中元素对应的结构体的数据.
func(pet Pets, man Man) map[string]Pets {
return map[string]Pets{
man.Name: pet,
}
}).ForEachT(func(petWithMan map[string]Pets) {
for key, value := range petWithMan {
fmt.Println(fmt.Sprintf("%v拥有一只宠物,它的名字叫做%v", key, value.Name))
}
})
} }
func Combine(query linq.Query) { func Select() {
bookList := MakeBook()
query := linq.From(bookList)
//筛选出结构体对应的元素
query.SelectT(func(book Book) string {
return book.Name
}).ForEachT(func(bookName string) {
fmt.Println(fmt.Sprintf("书名%v", bookName))
})
fmt.Println()
fmt.Println()
//根据下标进行返回,如果是跟下标有关的,则可以通过这个方法进行组合然后返回.
query.SelectIndexedT(func(index int, book Book) []string {
return []string{strconv.Itoa(index + 1), book.Name}
}).ForEachT(func(book []string) {
fmt.Println(fmt.Sprintf("第%v本书,书名%v", book[0], book[1]))
})
}
//OrderBy可以按照对应的规则进行排序,可以实现多重排序,需要注意的就是OrderBy是从到达,orderByDescending是从大到小
func OrderBy() {
bookList := MakeBook()
query := linq.From(bookList)
query = query.OrderByDescendingT(func(book Book) string {
return book.Name
}).ThenByDescendingT(func(book Book) string {
return book.Author
}).ThenByDescendingT(func(book Book) float64 {
return book.Money
}).Query
query.ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
fmt.Println()
fmt.Println()
//reverse: 把结果逆序
query.Reverse().ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
}
func Join() {
//任务和动物有关联,直接找到对应的关系,没有对应关系的数据不会处理,正常情况下应该用更单一的数据来做关联
persons, pets := MakeJoinData()
query1 := linq.From(persons)
query2 := linq.From(pets)
query1.JoinT(query2,
func(person Person) string {
return person.Name
},
func(pet Pet) string {
return pet.OwnerName
},
func(person Person, pet Pet) map[string]Pet {
petMap := make(map[string]Pet)
petMap[person.Name] = pet
return petMap
},
).ForEachT(func(petMap map[string]Pet) {
for key, value := range petMap {
fmt.Println(fmt.Sprintf("%v拥有一只宠物,它的名字叫做:%v", key, value.Name))
}
})
}
func Intersect() {
bookList1 := MakeBook1()
query1 := linq.From(bookList1)
bookList2 := MakeBook2()
query2 := linq.From(bookList2)
fmt.Println("输出对应的书籍元素,按照结构体判断交集")
query3 := query1.Intersect(query2)
query3.ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
fmt.Println()
fmt.Println("输出对应的书籍元素,按照元素判断交集")
query3 = query1.IntersectByT(query2, func(book Book) string {
return book.Author
})
query3.ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
//这边计算是按照结构体的一个元素进行比较。事实证明无论是否按照结构体的元素筛选,返回的都是完全相同的元素
fmt.Println()
fmt.Println("输出对应的书籍元素,按照元素判断交集2")
bookList1 = MakeBook1()
query1 = linq.From(bookList1)
bookList3 := MakeBook3()
query2 = linq.From(bookList3)
query3 = query2.IntersectByT(query1, func(book Book) string {
return book.Author
})
query3.ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
fmt.Println()
fmt.Println("判断是否会不重复的处理")
query1 = linq.From([]int{1, 2, 3, 4, 5, 3})
query2 = linq.From([]int{1, 3, 3, 78, 99, 0, 111})
query3 = query2.IntersectByT(query1, func(i int) int {
return i
})
fmt.Println(query3.Results())
}
func GroupBy() {
bookList1 := MakeBook1()
query := linq.From(bookList1)
fmt.Println("输出对应书名和作者")
//第一个func是分组的依据,第二个func是分组后返回的元素.
query = query.GroupByT(func(book Book) string {
return book.Author
}, func(book Book) Book {
return book
})
query.ForEachT(func(bookGroup linq.Group) {
fmt.Println(fmt.Sprintf("作者是%v", bookGroup.Key))
for _, item := range bookGroup.Group {
fmt.Println(fmt.Sprintf("书名%v,作者%v", item.(Book).Name, item.(Book).Author))
fmt.Println()
}
})
fmt.Println()
fmt.Println("输出对应书名")
bookList1 = MakeBook1()
query = linq.From(bookList1)
var nameGroups []linq.Group
query.GroupByT(
func(book Book) string { return book.Author },
func(book Book) string { return book.Name },
).ToSlice(&nameGroups)
for _, item := range nameGroups {
fmt.Println(fmt.Sprintf("作者是%v", item.Key))
for _, row := range item.Group {
fmt.Println(fmt.Sprintf("书名%v", row))
}
}
}
func Except() {
bookList1 := MakeBook1()
query1 := linq.From(bookList1)
bookList2 := MakeBook2()
query2 := linq.From(bookList2)
fmt.Println("输出对应书名和作者")
//判断结构结构体本身是否相等
query1.Except(query2).
ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
fmt.Println()
fmt.Println("输出对应书名和作者")
//判断结构体的某个字段是否出现
query1.ExceptByT(query2, func(book Book) string {
return book.Author
}).ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
}
func Distinct() {
bookList := MakeBook()
query := linq.From(bookList)
query = query.Append(Book{
Name: "Go语言",
Author: "Go",
Money: 100,
WordsNum: 1000,
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
})
bookList1 := make([]Book, 0)
query.ToSlice(&bookList1)
fmt.Println(fmt.Sprintf("筛选之前query中总共有%d个数据", query.Count()))
//这边的distinct如果是结构体,则判断的是结构体的所有值,如果是指针则判断的是指针地址.
query = query.Distinct()
fmt.Println(fmt.Sprintf("筛选之后query中总共有%d个数据", query.Count()))
fmt.Println()
fmt.Println("输出对应书名和作者")
query = query.Append(Book{
Name: "Go语言(第二版)",
Author: "Go",
Money: 100,
WordsNum: 1000,
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
})
//根据对应的规则来判断是否相同 -- 如果对应的字段一样,只会保留第一个找到的,后面的会被清除掉
query.DistinctByT(func(book Book) string {
return book.Author
}).ForEachT(func(book Book) {
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
})
}
func Combine() {
bookList := MakeBook()
query := linq.From(bookList)
query1 := query.Concat(query) //不会排除重复项 query1 := query.Concat(query) //不会排除重复项
query2 := query.Union(query) //会排除重复项 query2 := query.Union(query) //会排除重复项
fmt.Println(fmt.Sprintf("不会排除重复项的方法返回的元素个数是%d", len(query1.Results()))) fmt.Println(fmt.Sprintf("不会排除重复项的方法返回的元素个数是%d", len(query1.Results())))
fmt.Println(fmt.Sprintf("会排除重复项的方法返回的元素个数是%d", len(query2.Results()))) fmt.Println(fmt.Sprintf("会排除重复项的方法返回的元素个数是%d", len(query2.Results())))
query1 = query1.Append(Book{Name: "Last One"}) //加在原来的Query的最后面
query2 = query2.Prepend(Book{Name: "First One"}) //加在原来的Query的第一个
fmt.Println(fmt.Sprintf("最后一个元素是%v", query1.Last()))
fmt.Println(fmt.Sprintf("第一个元素是%v", query2.First()))
} }
func FirstAndLast(query linq.Query) { func FirstAndLast(query linq.Query) {
@@ -92,7 +457,9 @@ func Calculate() {
fmt.Println(fmt.Sprintf("最小的值为%d", query.Min())) fmt.Println(fmt.Sprintf("最小的值为%d", query.Min()))
} }
func AnyWith(query linq.Query) { func AnyWith() {
bookList := MakeBook()
query := linq.From(bookList)
result := query.AnyWith(PublishTimeBeforeFunc) //判断是否有任意个元素满足条件 result := query.AnyWith(PublishTimeBeforeFunc) //判断是否有任意个元素满足条件
fmt.Println(fmt.Sprintf("是否有任意书的发表时间早于2020年1月1号,答案是%v", result)) fmt.Println(fmt.Sprintf("是否有任意书的发表时间早于2020年1月1号,答案是%v", result))
@@ -100,7 +467,9 @@ func AnyWith(query linq.Query) {
fmt.Println(fmt.Sprintf("是否有任意书的发表时间晚于2021年1月1号,答案是%v", result)) fmt.Println(fmt.Sprintf("是否有任意书的发表时间晚于2021年1月1号,答案是%v", result))
} }
func All(query linq.Query) { func All() {
bookList := MakeBook()
query := linq.From(bookList)
result := query.All(PublishTimeBeforeFunc) result := query.All(PublishTimeBeforeFunc)
fmt.Println(fmt.Sprintf("是否所有的书的发表时间都早于2020年1月1号,答案是%v", result)) fmt.Println(fmt.Sprintf("是否所有的书的发表时间都早于2020年1月1号,答案是%v", result))
@@ -108,10 +477,12 @@ func All(query linq.Query) {
fmt.Println(fmt.Sprintf("是否所有的书的发表时间都晚于2018年1月1号,答案是%v", result)) fmt.Println(fmt.Sprintf("是否所有的书的发表时间都晚于2018年1月1号,答案是%v", result))
} }
func Aggregate(query linq.Query) { func Aggregate() {
bookList := MakeBook()
query := linq.From(bookList)
// 这边的聚合操作其实就是【自定义对应的比较方法】。 // 这边的聚合操作其实就是【自定义对应的比较方法】。
// 根据注释,第一次拿到的是数组的第一个元素,然后跟第二个元素进行比较,如果第二个元素符合条件则【替换第一个元素】,否则当前聚合操作还是持有第一个元素。 // 根据注释,第一次拿到的是数组的第一个元素,然后跟第二个元素进行比较,如果第二个元素符合条件则【替换第一个元素】,否则当前聚合操作还是持有第一个元素。
// 以此类推后面的元素 // 以此类推后面的元素
result := query.Aggregate(AggregateFunc).(*Book) result := query.Aggregate(AggregateFunc).(Book)
fmt.Println(fmt.Sprintf("聚合操作查询出的结果是【%s】这本书,它的发布时间最早为:%v", result.Name, timed.GetTimeDefaultFormatString(result.PublishTime.Unix()))) fmt.Println(fmt.Sprintf("聚合操作查询出的结果是【%s】这本书,它的发布时间最早为:%v", result.Name, timed.GetTimeDefaultFormatString(result.PublishTime.Unix())))
} }