feat(Go-Tool):2020/11/12:新增linq包使用示例(未完成)
This commit is contained in:
+212
@@ -0,0 +1,212 @@
|
||||
package linq
|
||||
|
||||
import "sort"
|
||||
|
||||
type order struct {
|
||||
selector func(interface{}) interface{}
|
||||
compare comparer
|
||||
desc bool
|
||||
}
|
||||
|
||||
// OrderedQuery is the type returned from OrderBy, OrderByDescending
|
||||
// ThenBy and ThenByDescending functions.
|
||||
type OrderedQuery struct {
|
||||
Query
|
||||
original Query
|
||||
orders []order
|
||||
}
|
||||
|
||||
// OrderBy sorts the elements of a collection in ascending order.
|
||||
// Elements are sorted according to a key.
|
||||
func (q Query) OrderBy(
|
||||
selector func(interface{}) interface{}) OrderedQuery {
|
||||
return OrderedQuery{
|
||||
orders: []order{{selector: selector}},
|
||||
original: q,
|
||||
Query: Query{
|
||||
Iterate: func() Iterator {
|
||||
items := q.sort([]order{{selector: selector}})
|
||||
len := len(items)
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
item = items[index]
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// OrderByDescending sorts the elements of a collection in descending order.
|
||||
// Elements are sorted according to a key.
|
||||
func (q Query) OrderByDescending(
|
||||
selector func(interface{}) interface{}) OrderedQuery {
|
||||
return OrderedQuery{
|
||||
orders: []order{{selector: selector, desc: true}},
|
||||
original: q,
|
||||
Query: Query{
|
||||
Iterate: func() Iterator {
|
||||
items := q.sort([]order{{selector: selector, desc: true}})
|
||||
len := len(items)
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
item = items[index]
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ThenBy performs a subsequent ordering of the elements in a collection
|
||||
// in ascending order. This method enables you to specify multiple sort criteria
|
||||
// by applying any number of ThenBy or ThenByDescending methods.
|
||||
func (oq OrderedQuery) ThenBy(
|
||||
selector func(interface{}) interface{}) OrderedQuery {
|
||||
return OrderedQuery{
|
||||
orders: append(oq.orders, order{selector: selector}),
|
||||
original: oq.original,
|
||||
Query: Query{
|
||||
Iterate: func() Iterator {
|
||||
items := oq.original.sort(append(oq.orders, order{selector: selector}))
|
||||
len := len(items)
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
item = items[index]
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ThenByDescending performs a subsequent ordering of the elements in a collection
|
||||
// in descending order. This method enables you to specify multiple sort criteria
|
||||
// by applying any number of ThenBy or ThenByDescending methods.
|
||||
func (oq OrderedQuery) ThenByDescending(
|
||||
selector func(interface{}) interface{}) OrderedQuery {
|
||||
return OrderedQuery{
|
||||
orders: append(oq.orders, order{selector: selector, desc: true}),
|
||||
original: oq.original,
|
||||
Query: Query{
|
||||
Iterate: func() Iterator {
|
||||
items := oq.original.sort(append(oq.orders, order{selector: selector, desc: true}))
|
||||
len := len(items)
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
item = items[index]
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Sort returns a new query by sorting elements with provided less function
|
||||
// in ascending order. The comparer function should return true if the parameter i
|
||||
// is less than j. While this method is uglier than chaining OrderBy, OrderByDescending,
|
||||
// ThenBy and ThenByDescending methods, it's performance is much better.
|
||||
func (q Query) Sort(less func(i, j interface{}) bool) Query {
|
||||
return Query{
|
||||
Iterate: func() Iterator {
|
||||
items := q.lessSort(less)
|
||||
len := len(items)
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
item = items[index]
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type sorter struct {
|
||||
items []interface{}
|
||||
less func(i, j interface{}) bool
|
||||
}
|
||||
|
||||
func (s sorter) Len() int {
|
||||
return len(s.items)
|
||||
}
|
||||
|
||||
func (s sorter) Swap(i, j int) {
|
||||
s.items[i], s.items[j] = s.items[j], s.items[i]
|
||||
}
|
||||
|
||||
func (s sorter) Less(i, j int) bool {
|
||||
return s.less(s.items[i], s.items[j])
|
||||
}
|
||||
|
||||
func (q Query) sort(orders []order) (r []interface{}) {
|
||||
next := q.Iterate()
|
||||
for item, ok := next(); ok; item, ok = next() {
|
||||
r = append(r, item)
|
||||
}
|
||||
|
||||
for i, j := range orders {
|
||||
orders[i].compare = getComparer(j.selector(r[0]))
|
||||
}
|
||||
|
||||
s := sorter{
|
||||
items: r,
|
||||
less: func(i, j interface{}) bool {
|
||||
for _, order := range orders {
|
||||
x, y := order.selector(i), order.selector(j)
|
||||
switch order.compare(x, y) {
|
||||
case 0:
|
||||
continue
|
||||
case -1:
|
||||
return !order.desc
|
||||
default:
|
||||
return order.desc
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}}
|
||||
|
||||
sort.Sort(s)
|
||||
return
|
||||
}
|
||||
|
||||
func (q Query) lessSort(less func(i, j interface{}) bool) (r []interface{}) {
|
||||
next := q.Iterate()
|
||||
for item, ok := next(); ok; item, ok = next() {
|
||||
r = append(r, item)
|
||||
}
|
||||
|
||||
s := sorter{items: r, less: less}
|
||||
|
||||
sort.Sort(s)
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user