blob: 0c5f69c2927d6f6f781d3d51b865887472b57093 [file] [log] [blame]
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package slice
import "reflect"
var trueVal = reflect.ValueOf(true)
// Nub returns v with duplicates removed. It keeps the first instance
// of each distinct value and preserves their order.
func Nub(v T) T {
rv := reflectSlice(v)
indexes := make([]int, 0)
set := reflect.MakeMap(reflect.MapOf(rv.Type().Elem(), trueVal.Type()))
for i, l := 0, rv.Len(); i < l; i++ {
x := rv.Index(i)
if set.MapIndex(x).IsValid() {
continue
}
set.SetMapIndex(x, trueVal)
indexes = append(indexes, i)
}
return Select(v, indexes)
}
// NubAppend is equivalent to appending all of the slices in vs and
// then calling Nub on the result, but more efficient.
func NubAppend(vs ...T) T {
if len(vs) == 0 {
return nil
}
rv := reflectSlice(vs[0])
set := reflect.MakeMap(reflect.MapOf(rv.Type().Elem(), trueVal.Type()))
out := reflect.MakeSlice(rv.Type(), 0, 0)
for _, v := range vs {
rv := reflectSlice(v)
for i, l := 0, rv.Len(); i < l; i++ {
x := rv.Index(i)
if set.MapIndex(x).IsValid() {
continue
}
set.SetMapIndex(x, trueVal)
out = reflect.Append(out, x)
}
}
return out.Interface()
}