go-linq 是.net linq 的golang 实现,使用简单灵活,而且支持多种操作模式,同时也支持基于范型函数,使得代码更清晰
linq 参考格式
From(slice) .Where(predicate) .Select(selector) .Union(data)
参考使用
集成了mitchellh/mapstructure 一个方便的数据类型转换工具
package main
import (
"log"
. "github.com/ahmetb/go-linq/v3"
"github.com/mitchellh/mapstructure"
)
type MyQuery Query
func (q MyQuery) GreaterThan(threshold int) Query {
return Query{
Iterate: func() Iterator {
next := q.Iterate()
return func() (item interface{}, ok bool) {
for item, ok = next(); ok; item, ok = next() {
if item.(int) > threshold {
return
}
}
return
}
},
}
}
func main() {
type Person struct {
Name string
Age int
Emails []string
Extra map[string]string
}
input := map[string]interface{}{
"name": "Mitchell",
"age": 91,
"emails": []string{"one", "two", "three"},
"extra": map[string]string{
"twitter": "mitchellh",
},
}
// map 转struct
var result Person
err := mapstructure.Decode(input, &result)
if err != nil {
panic(err)
}
var users []Person = make([]Person, 2)
var names []string
var names2 []struct {
name string
age int
}
users = append(users, result)
// linq 使用
From(users).Where(func(u interface{}) bool {
p := u.(Person)
return p.Age > 10
}).SelectT(func(p Person) string {
return p.Name
}).ToSlice(&names)
for _, name := range names {
log.Println(name)
}
From(users).Where(func(u interface{}) bool {
p := u.(Person)
return p.Age > 10
}).Select(func(p interface{}) interface{} {
person := p.(Person)
return struct {
name string
age int
}{
name: person.Name,
age: person.Age,
}
}).ToSlice(&names2)
for _, name := range names2 {
log.Println(name)
}
// 测试自定义query
results := MyQuery(Range(1, 100)).GreaterThan(97).Results()
for _, result := range results {
log.Println(result)
}
}
说明
mitchellh/mapstructure 与go-linq 是一个很不错的golang 工具包,可以简化我们好多开发工作
参考资料
https://github.com/ahmetb/go-linq
https://github.com/mitchellh/mapstructure