goiterator

How to convert iter.Seq2[int, E] to iter.Seq[E] in go 1.23


For instance slices.Backward has the signature

func Backward[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]

when slices.Collect has the signature

func Collect[E any](seq iter.Seq[E]) []E

How can i use them together?

it := slices.Backward([]int{1, 2, 3})
// collect back `it` to a slice 
// slices.Collect(it) -> in call to slices.Collect, type iter.Seq2[int, int] of it does not match iter.Seq[E] (cannot infer E)

Solution

  • iter.Seq2 is an iterator which provides both keys (or indicies) and values. There's no builtin conversion to drop the keys (so we get an iter.Seq as a result), but it's pretty simple to create one:

    func Values[K, V any](seq iter.Seq2[K, V]) iter.Seq[V] {
        return func(yield func(V) bool) {
            for _, v := range seq {
                if !yield(v) {
                    return
                }
            }
        }
    }
    

    Testing it:

    is := []int{1, 2, 3, 4}
    
    seq2 := slices.Backward(is)
    
    for i, v := range seq2 {
        fmt.Println(i, v)
    }
    
    seq := Values(seq2)
    
    values := slices.Collect(seq)
    fmt.Println(values)
    
    for v := range seq {
        fmt.Println(v)
    }
    

    Output (try it on the Go Playground):

    3 4
    2 3
    1 2
    0 1
    [4 3 2 1]
    4
    3
    2
    1