Description
Proposal Details
Proposal details
slices
package provides useful Chunk
function that batches a slice into chunks.
A fellow iter
alternative would be extremely helpful to work with iterators.
Below is a sample implementation that I'm using in my projects (rewritten to fit into iter
package):
package iter
// ...
// ChunkIter works like slices.Chunk but with iterators,
// i. e. iterates over it and yields batches of size n.
// Panics if n is less than 1.
func ChunkIter[I Seq[V], V any](it I, n int) Seq[[]V] {
if n < 1 {
panic("cannot be less than 1")
}
return func(yield func([]V) bool) {
batch := []V{}
for v := range it {
batch = append(batch, v)
if len(batch) == n {
if !yield(batch) {
return
}
batch = []V{}
}
}
if len(batch) > 0 {
yield(batch)
}
}
}
// ChunkIter2 works like slices.ChunkIter,
// but yields pairs of batches of size n.
// Panics if n is less than 1.
func ChunkIter2[I Seq2[K, V], K any, V any](it I, n int) Seq2[[]K, []V] {
if n < 1 {
panic("cannot be less than 1")
}
return func(yield func([]K, []V) bool) {
kbatch := []K{}
vbatch := []V{}
for k, v := range it {
kbatch = append(kbatch, k)
vbatch = append(vbatch, v)
if len(kbatch) == n {
if !yield(kbatch, vbatch) {
return
}
kbatch = []K{}
vbatch = []V{}
}
}
if len(kbatch) > 0 {
yield(kbatch, vbatch)
}
}
}
Even though iterators are great, I would argue that implementing them results in code that is rather hard to read. Thus I find this snippet complex enough to be considered for addition into iter
package.
Adding playground link that demonstrates and tests this implementation.
This is my first proposal for the gopher community, so please feel free to let me know if I should provide more details or update anything.
EDIT: After some consideration, I think ChunkSeq
and ChunkSeq2
would probably be more appropriate than ChunkIter
/ ChunkIter2
.