152 lines
3.4 KiB
Go
152 lines
3.4 KiB
Go
package linq
|
|
|
|
// 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
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
// 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(outer, item)
|
|
return
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
// 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(outer, item)
|
|
return
|
|
}
|
|
},
|
|
}
|
|
}
|