123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- package help
- // SelectMany projects each element of a collection to a Query, iterates and
- // flattens the resulting collection into one collection.
- func (q Query) SelectMany(selector func(interface{}) Query) Query {
- return Query{
- Iterate: func() Iterator {
- outernext := q.Iterate()
- var inner interface{}
- var innernext Iterator
- return func() (item interface{}, ok bool) {
- for !ok {
- if inner == nil {
- inner, ok = outernext()
- if !ok {
- return
- }
- innernext = selector(inner).Iterate()
- }
- item, ok = innernext()
- if !ok {
- inner = nil
- }
- }
- return
- }
- },
- }
- }
- // SelectManyT is the typed version of SelectMany.
- //
- // - selectorFn is of type "func(TSource)Query"
- //
- // NOTE: SelectMany has better performance than SelectManyT.
- func (q Query) SelectManyT(selectorFn interface{}) Query {
- selectManyGenericFunc, err := newGenericFunc(
- "SelectManyT", "selectorFn", selectorFn,
- simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(Query))),
- )
- if err != nil {
- panic(err)
- }
- selectorFunc := func(inner interface{}) Query {
- return selectManyGenericFunc.Call(inner).(Query)
- }
- return q.SelectMany(selectorFunc)
- }
- // SelectManyIndexed projects each element of a collection to a Query, iterates
- // and flattens the resulting collection into one collection.
- //
- // The first argument to selector represents the zero-based index of that
- // element in the source collection. This can be useful if the elements are in a
- // known order and you want to do something with an element at a particular
- // index, for example. It can also be useful if you want to retrieve the index
- // of one or more elements. The second argument to selector represents the
- // element to process.
- func (q Query) SelectManyIndexed(selector func(int, interface{}) Query) Query {
- return Query{
- Iterate: func() Iterator {
- outernext := q.Iterate()
- index := 0
- var inner interface{}
- var innernext Iterator
- return func() (item interface{}, ok bool) {
- for !ok {
- if inner == nil {
- inner, ok = outernext()
- if !ok {
- return
- }
- innernext = selector(index, inner).Iterate()
- index++
- }
- item, ok = innernext()
- if !ok {
- inner = nil
- }
- }
- return
- }
- },
- }
- }
- // SelectManyIndexedT is the typed version of SelectManyIndexed.
- //
- // - selectorFn is of type "func(int,TSource)Query"
- //
- // NOTE: SelectManyIndexed has better performance than SelectManyIndexedT.
- func (q Query) SelectManyIndexedT(selectorFn interface{}) Query {
- selectManyIndexedGenericFunc, err := newGenericFunc(
- "SelectManyIndexedT", "selectorFn", selectorFn,
- simpleParamValidator(newElemTypeSlice(new(int), new(genericType)), newElemTypeSlice(new(Query))),
- )
- if err != nil {
- panic(err)
- }
- selectorFunc := func(index int, inner interface{}) Query {
- return selectManyIndexedGenericFunc.Call(index, inner).(Query)
- }
- return q.SelectManyIndexed(selectorFunc)
- }
- // SelectManyBy projects each element of a collection to a Query, iterates and
- // flattens the resulting collection into one collection, and invokes a result
- // selector function on each element therein.
- func (q Query) SelectManyBy(selector func(interface{}) Query,
- resultSelector func(interface{}, interface{}) interface{}) Query {
- return Query{
- Iterate: func() Iterator {
- outernext := q.Iterate()
- var outer interface{}
- var innernext Iterator
- return func() (item interface{}, ok bool) {
- for !ok {
- if outer == nil {
- outer, ok = outernext()
- if !ok {
- return
- }
- innernext = selector(outer).Iterate()
- }
- item, ok = innernext()
- if !ok {
- outer = nil
- }
- }
- item = resultSelector(item, outer)
- return
- }
- },
- }
- }
- // SelectManyByT is the typed version of SelectManyBy.
- //
- // - selectorFn is of type "func(TSource)Query"
- // - resultSelectorFn is of type "func(TSource,TCollection)TResult"
- //
- // NOTE: SelectManyBy has better performance than SelectManyByT.
- func (q Query) SelectManyByT(selectorFn interface{},
- resultSelectorFn interface{}) Query {
- selectorGenericFunc, err := newGenericFunc(
- "SelectManyByT", "selectorFn", selectorFn,
- simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(Query))),
- )
- if err != nil {
- panic(err)
- }
- selectorFunc := func(outer interface{}) Query {
- return selectorGenericFunc.Call(outer).(Query)
- }
- resultSelectorGenericFunc, err := newGenericFunc(
- "SelectManyByT", "resultSelectorFn", resultSelectorFn,
- simpleParamValidator(newElemTypeSlice(new(genericType), new(genericType)), newElemTypeSlice(new(genericType))),
- )
- if err != nil {
- panic(err)
- }
- resultSelectorFunc := func(outer interface{}, item interface{}) interface{} {
- return resultSelectorGenericFunc.Call(outer, item)
- }
- return q.SelectManyBy(selectorFunc, resultSelectorFunc)
- }
- // SelectManyByIndexed projects each element of a collection to a Query,
- // iterates and flattens the resulting collection into one collection, and
- // invokes a result selector function on each element therein. The index of each
- // source element is used in the intermediate projected form of that element.
- func (q Query) SelectManyByIndexed(selector func(int, interface{}) Query,
- resultSelector func(interface{}, interface{}) interface{}) Query {
- return Query{
- Iterate: func() Iterator {
- outernext := q.Iterate()
- index := 0
- var outer interface{}
- var innernext Iterator
- return func() (item interface{}, ok bool) {
- for !ok {
- if outer == nil {
- outer, ok = outernext()
- if !ok {
- return
- }
- innernext = selector(index, outer).Iterate()
- index++
- }
- item, ok = innernext()
- if !ok {
- outer = nil
- }
- }
- item = resultSelector(item, outer)
- return
- }
- },
- }
- }
- // SelectManyByIndexedT is the typed version of SelectManyByIndexed.
- //
- // - selectorFn is of type "func(int,TSource)Query"
- // - resultSelectorFn is of type "func(TSource,TCollection)TResult"
- //
- // NOTE: SelectManyByIndexed has better performance than
- // SelectManyByIndexedT.
- func (q Query) SelectManyByIndexedT(selectorFn interface{},
- resultSelectorFn interface{}) Query {
- selectorGenericFunc, err := newGenericFunc(
- "SelectManyByIndexedT", "selectorFn", selectorFn,
- simpleParamValidator(newElemTypeSlice(new(int), new(genericType)), newElemTypeSlice(new(Query))),
- )
- if err != nil {
- panic(err)
- }
- selectorFunc := func(index int, outer interface{}) Query {
- return selectorGenericFunc.Call(index, outer).(Query)
- }
- resultSelectorGenericFunc, err := newGenericFunc(
- "SelectManyByIndexedT", "resultSelectorFn", resultSelectorFn,
- simpleParamValidator(newElemTypeSlice(new(genericType), new(genericType)), newElemTypeSlice(new(genericType))),
- )
- if err != nil {
- panic(err)
- }
- resultSelectorFunc := func(outer interface{}, item interface{}) interface{} {
- return resultSelectorGenericFunc.Call(outer, item)
- }
- return q.SelectManyByIndexed(selectorFunc, resultSelectorFunc)
- }
|