1

Thanks to the new 1.18 beta release of Go, we can use new Generic feature. First thing I tried to do is to implement Map / Filter / Reduce to any slice.

So with a Generic Slice Type defined as :

type Slice[T any] []T

I can implements my two first methods Map and Filter as follows:

func (s Slice[T]) Map(callback func(item T, indice int, arr Slice[T]) T) Slice[T] {
    temp := make([]T, 0)
    for i, v := range s {
        temp = append(temp, callback(v, i, s))
    }
    return temp
}

func (s Slice[T]) Filter(callback func(item T, indice int, arr Slice[T]) bool) Slice[T] {
    temp := make([]T, 0)
    for i, v := range s {
        if callback(v, i, s) {
            temp = append(temp, v)
        }
    }
    return temp
}

This works fine as follows:

s := Slice[int]{1, 2, 3}
    
    mapped := s.Map(func(item int, indice int, arr Slice[int]) int {
        return item*2 + len(arr) + indice
    })
    
    fmt.Println(mapped) // Print : [5 8 11]
    
    filtered := s.Filter(func(item int, _ int, _ Slice[int] ) bool {
        return item%2==0
    })
    
    fmt.Println(filtered) // Print : [2]

Now, I'd like to implements my "Reduce" function, in the same way the Javascript Reduce works... In the Javascript version, we pass a callback with the accumulator, the current element, the index of the current element in the array and the array itself. It should return the accumulator; and a second argument: the initial value.

So, the slice should be generic over T, but the accumulator could be another generic value

I tried to code something like:

func (s Slice[T]) Reduce[V any](callback func(accumulator V, current T) V, initial V) V {
    ...
}

With this signature, based on a slice of T, my method will take a callback and an initial value of another generic type V. The callback accumulator is from this second generic V (and will return V) based on each current element of type T.

Unfortunately this code produces:

syntax error: method must have no type parameters

It seems we can't use any other type parameter except one declared on the receiver.

Is there any solution for this use case?

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Darth Yoh
  • 41
  • 4

0 Answers0