feat(Go-Tool):2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组)
This commit is contained in:
+172
@@ -0,0 +1,172 @@
|
||||
package linq
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Iterator is an alias for function to iterate over data.
|
||||
type Iterator func() (item interface{}, ok bool)
|
||||
|
||||
// Query is the type returned from query functions. It can be iterated manually
|
||||
// as shown in the example.
|
||||
type Query struct {
|
||||
Iterate func() Iterator
|
||||
}
|
||||
|
||||
// KeyValue is a type that is used to iterate over a map (if query is created
|
||||
// from a map). This type is also used by ToMap() method to output result of a
|
||||
// query into a map.
|
||||
type KeyValue struct {
|
||||
Key interface{}
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
// Iterable is an interface that has to be implemented by a custom collection in
|
||||
// order to work with linq.
|
||||
type Iterable interface {
|
||||
Iterate() Iterator
|
||||
}
|
||||
|
||||
// From initializes a linq query with passed slice, array or map as the source.
|
||||
// String, channel or struct implementing Iterable interface can be used as an
|
||||
// input. In this case From delegates it to FromString, FromChannel and
|
||||
// FromIterable internally.
|
||||
func From(source interface{}) Query {
|
||||
src := reflect.ValueOf(source)
|
||||
|
||||
switch src.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
len := src.Len()
|
||||
|
||||
return Query{
|
||||
Iterate: func() Iterator {
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
item = src.Index(index).Interface()
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
case reflect.Map:
|
||||
len := src.Len()
|
||||
|
||||
return Query{
|
||||
Iterate: func() Iterator {
|
||||
index := 0
|
||||
keys := src.MapKeys()
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
key := keys[index]
|
||||
item = KeyValue{
|
||||
Key: key.Interface(),
|
||||
Value: src.MapIndex(key).Interface(),
|
||||
}
|
||||
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
case reflect.String:
|
||||
return FromString(source.(string))
|
||||
case reflect.Chan:
|
||||
return FromChannel(source.(chan interface{}))
|
||||
default:
|
||||
return FromIterable(source.(Iterable))
|
||||
}
|
||||
}
|
||||
|
||||
// FromChannel initializes a linq query with passed channel, linq iterates over
|
||||
// channel until it is closed.
|
||||
func FromChannel(source <-chan interface{}) Query {
|
||||
return Query{
|
||||
Iterate: func() Iterator {
|
||||
return func() (item interface{}, ok bool) {
|
||||
item, ok = <-source
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// FromString initializes a linq query with passed string, linq iterates over
|
||||
// runes of string.
|
||||
func FromString(source string) Query {
|
||||
runes := []rune(source)
|
||||
len := len(runes)
|
||||
|
||||
return Query{
|
||||
Iterate: func() Iterator {
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
ok = index < len
|
||||
if ok {
|
||||
item = runes[index]
|
||||
index++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// FromIterable initializes a linq query with custom collection passed. This
|
||||
// collection has to implement Iterable interface, linq iterates over items,
|
||||
// that has to implement Comparable interface or be basic types.
|
||||
func FromIterable(source Iterable) Query {
|
||||
return Query{
|
||||
Iterate: source.Iterate,
|
||||
}
|
||||
}
|
||||
|
||||
// Range generates a sequence of integral numbers within a specified range.
|
||||
func Range(start, count int) Query {
|
||||
return Query{
|
||||
Iterate: func() Iterator {
|
||||
index := 0
|
||||
current := start
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
if index >= count {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
item, ok = current, true
|
||||
|
||||
index++
|
||||
current++
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Repeat generates a sequence that contains one repeated value.
|
||||
func Repeat(value interface{}, count int) Query {
|
||||
return Query{
|
||||
Iterate: func() Iterator {
|
||||
index := 0
|
||||
|
||||
return func() (item interface{}, ok bool) {
|
||||
if index >= count {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
item, ok = value, true
|
||||
|
||||
index++
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user