Search code examples
goiterator

How to concatenate two Go 1.23 iter.Seq[E] together?


Go 1.23 comes with the new iter package and range-over-func feature.

Given two iterators, what's the correct way to combine them together?

import "slices"

func main() {
    a := []int{1, 2, 3, 4}
    b := []int{5, 6, 7, 8}

    i := slices.Values(a) // i is iter.Seq[int]
    j := slices.Values(b) // j is iter.Seq[int]

    // ???
}

The goal here is to iterate over both slices' elements in order, from 1 to 8. Apparently there isn't any ready-made helper in the slices package, is there?


Solution

  • True, the iter package provides no function for concatenating two iter.Seq[E], but you can implement one easily enough. Below is a Concat function (borrowed from my jub0bs/iterutil package) that takes a variadic parameter:

    package main
    
    import (
        "fmt"
        "iter"
        "slices"
    )
    
    // borrowed from https://pkg.go.dev/github.com/jub0bs/iterutil#Concat
    func Concat[E any](seqs ...iter.Seq[E]) iter.Seq[E] {
        return func(yield func(E) bool) {
            for _, seq := range seqs {
                for e := range seq {
                    if !yield(e) {
                        return
                    }
                }
            }
        }
    }
    
    func main() {
        a := []int{1, 2, 3, 4}
        b := []int{5, 6, 7, 8}
    
        for i := range Concat(slices.Values(a), slices.Values(b)) {
            fmt.Print(i, ",")
        }
    }
    

    Output:

    1,2,3,4,5,6,7,8,
    

    (Playground)