2

I have this function and i would like to make it be able to receive all types of slices, not only []string, but []int and so on... I would like to know if is there some way to abstract the type when passing the parameter to the function header or if i should do other thing to accomplish that.

package removeDuplicate

// RemoveDuplicate remove duplicate items from slice setting it to arr2
func RemoveDuplicate(arr []string) []string {
    arr2 := arr[:1]
Loop:
    for i := 1; i < len(arr); {
        for j := 0; j < len(arr2); {
            if arr[i] != arr[j] {
                j++
            } else {
                i++
                continue Loop
            }
        }
        arr2 = append(arr2, arr[i])
        i++
    }
    return arr2
}

Thanks in advance =]

3
  • 1
    These are slices, not arrays. It is important because with slices you can operate on the same data, while arrays are separate values. Commented Jul 11, 2015 at 9:59
  • Side note: if the slice (as already noted, not an array) might be large then a better implementation would be to construct a map (actually a set) from the input slice and then turn the map keys into a slice for return. If this kind of thing is done often then the original data type should likely be changed to be a map (or a compound object that includes a map). Commented Jul 11, 2015 at 16:18
  • Yeah, i should say slice in this case. But because a slice describes a section of an array, it's something make me confused why i cant call it as array - in a more generalist way. Commented Jul 11, 2015 at 17:26

2 Answers 2

2

If you alter the function signature to accept interface{} you can get something that works on built in types.

package main

import "fmt"

func main() {
    x := []interface{}{"bob", "doug", "bob"}
    fmt.Println(RemoveDuplicate(x))
    y := []interface{}{1, 3, 1}
    fmt.Println(RemoveDuplicate(y))
    z := []interface{}{"bob", "2", "doug", 3, 2, "bob"}
    fmt.Println(RemoveDuplicate(z)) 
}

func RemoveDuplicate(arr []interface{}) []interface{} {
    arr2 := arr[:1]
Loop:
    for i := 1; i < len(arr); {
        for j := 0; j < len(arr2); {
            if arr[i] != arr[j] {
                j++
            } else {
                i++
                continue Loop
            }
        }
        arr2 = append(arr2, arr[i])
        i++
    }
    return arr2
}

Have a look at the FAQ Can I convert a []T to an []interface{}? (and the one before) for more information.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it works perfectly and it seems very idiomatic as well.
0

Any kind of generic algorithms in Go can be implemented with either of two mechanisms: interfaces and reflection. With interfaces, you can do it similarly to the sort package:

type Slice interface {
    Len() int
    Swap(i, j int)
    Eq(i, j int) bool
    SubSlice(i, j int) Slice
}

func RemoveDuplicate(s Slice) Slice {
    n := 1
Loop:
    for i := 1; i < s.Len(); i++ {
        for j := 0; j < n; j++ {
            if s.Eq(i, j) {
                continue Loop
            }
        }
        s.Swap(n, i)
        n++
    }
    return s.SubSlice(0, n)
}

Playground with ints and strings: http://play.golang.org/p/WwC27eP72n.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.