diff --git a/collection/slice.go b/collection/slice.go index 2e8f168..dbe9e3e 100644 --- a/collection/slice.go +++ b/collection/slice.go @@ -1,5 +1,9 @@ package collection +import ( + "slices" +) + // Slice crée un slice générique contenant les valeurs d’entrée. func Slice[T any](in ...T) (out []any) { out = make([]any, len(in)) @@ -12,41 +16,34 @@ func Slice[T any](in ...T) (out []any) { } // Add ajoute les valeurs d’entrée en fin du slice. -func Add[T any](s *([]T), in ...T) { +func Add[T any, S ~[]T](s *S, in ...T) { *s = append(*s, in...) } // Insert ajoute les valeurs d’entrée en début du slice. -func Insert[T any](s *([]T), in ...T) { - *s = append(in, (*s)...) +func Insert[T any, S ~[]T](s *S, in ...T) { + *s = slices.Insert(*s, 0, in...) } // InsertAt ajoute les valeurs d’entrée à l’index i du slice. // - Si l’index est inférieur à 0, agit comme Insert. // - Si l’index est supérieur ou égal à la taille du slice, agit comme Add. -func InsertAt[T any](s *([]T), i int, in ...T) { +func InsertAt[T any, S ~[]T](s *S, i int, in ...T) { + if i <= 0 { Insert(s, in...) - return } else if i >= len(*s) { Add(s, in...) - return + } else { + *s = slices.Insert(*s, i, in...) } - - l1, l2 := len(*s), len(in) - result := make([]T, l1+l2) - copy(result[:i], (*s)[:i]) - copy(result[i:i+l2], in) - copy(result[i+l2:], (*s)[i:]) - - *s = result } // Diff retourne un slice contenant les entrées de s1 qui ne sont pas dans s2. -func Diff[T comparable](s1, s2 []T) (out []T) { - ss := NewSet(s2...) +func Diff[T comparable, S ~[]T](in1, in2 S) (out S) { + ss := NewSet(in2...) - for _, e := range s1 { + for _, e := range in1 { if !ss.Contains(e) { Add(&out, e) } @@ -56,10 +53,10 @@ func Diff[T comparable](s1, s2 []T) (out []T) { } // Intersect retourne un slice contenant les entrées contenues à la fois dans s1 et s2. -func Intersect[T comparable](s1, s2 []T) (out []T) { - ss := NewSet(s2...) +func Intersect[T comparable, S ~[]T](in1, in2 S) (out S) { + ss := NewSet(in2...) - for _, e := range s1 { + for _, e := range in1 { if ss.Contains(e) { Add(&out, e) } @@ -69,10 +66,10 @@ func Intersect[T comparable](s1, s2 []T) (out []T) { } // Uniq supprime les valeurs redondantes du slice. -func Uniq[T comparable](s []T) (out []T) { +func Uniq[T comparable, S ~[]T](in S) (out S) { ss := NewSet[T]() - for _, e := range s { + for _, e := range in { if !ss.Contains(e) { ss.Add(e) Add(&out, e) @@ -83,49 +80,43 @@ func Uniq[T comparable](s []T) (out []T) { } // AddUniq ajoute les entrées en fin de slice si elles n’existent pas dans le slice. -func AddUniq[T comparable](s *([]T), in ...T) { +func AddUniq[T comparable, S ~[]T](s *S, in ...T) { in2 := Uniq(Diff(in, *s)) Add(s, in2...) } // InsertUniq ajoute les entrées en début de slice si elles n’existent pas dans le slice. -func InsertUniq[T comparable](s *([]T), in ...T) { +func InsertUniq[T comparable, S ~[]T](s *S, in ...T) { in2 := Uniq(Diff(in, *s)) Insert(s, in2...) } // InsertAtUniq ajoute les entrées dans le slice à la position donnée si elles n’existent pas dans le slice. -func InsertAtUniq[T comparable](s *([]T), i int, in ...T) { +func InsertAtUniq[T comparable, S ~[]T](s *S, i int, in ...T) { in2 := Uniq(Diff(in, *s)) InsertAt(s, i, in2...) } // Contains retourne vrai si le slice contient la valeur d’entrée. -func Contains[T comparable](s []T, in T) bool { - for _, e := range s { - if e == in { - return true - } - } - - return false +func Contains[T comparable, S ~[]T](s S, in T) bool { + return slices.Contains(s, in) } // ContainsOneOf retourne vrai si le slice contient une des valeurs d’entrée. -func ContainsOneOf[T comparable](s []T, in ...T) bool { +func ContainsOneOf[T comparable, S ~[]T](s S, in ...T) bool { return NewSet(s...).ContainsOneOf(in...) } // ContainsAll retourne vrai si le slice contient toutes les valeurs d’entrée. -func ContainsAll[T comparable](s []T, in ...T) bool { +func ContainsAll[T comparable, S ~[]T](s S, in ...T) bool { return NewSet(s...).ContainsAll(in...) } // Maps retourne un slice à partir d’un autre slice en appliquant une fonction de transformation pour chaque valeur. -func Maps[T1, T2 any](s []T1, f func(T1) T2) (out []T2) { - out = make([]T2, len(s)) +func Maps[T1, T2 any, S1 ~[]T1, S2 ~[]T2](in S1, f func(T1) T2) (out S2) { + out = make(S2, len(in)) - for i, e := range s { + for i, e := range in { out[i] = f(e) } @@ -133,8 +124,8 @@ func Maps[T1, T2 any](s []T1, f func(T1) T2) (out []T2) { } // Filter retourne un nouveau slice dont les valeurs passent la fonction. -func Filter[T any](s []T, f func(T) bool) (out []T) { - for _, e := range s { +func Filter[T any, S ~[]T](in S, f func(T) bool) (out S) { + for _, e := range in { if f(e) { Add(&out, e) } @@ -144,12 +135,12 @@ func Filter[T any](s []T, f func(T) bool) (out []T) { } // Reduce applique une fonction à tous les éléments dont le résultat sert à la prochaine itération. -func Reduce[T any](s []T, f func(T, T) T, initial ...T) (out T) { +func Reduce[T any, S ~[]T](in S, f func(T, T) T, initial ...T) (out T) { if len(initial) > 0 { out = initial[0] } - for _, e := range s { + for _, e := range in { out = f(out, e) } @@ -157,10 +148,10 @@ func Reduce[T any](s []T, f func(T, T) T, initial ...T) (out T) { } // Reverse inverse l’ordre du slice. -func Reverse[T any](s []T) (out []T) { - l := len(s) - out = make([]T, l) - for i, e := range s { +func Reverse[T any, S ~[]T](in S) (out S) { + l := len(in) + out = make(S, l) + for i, e := range in { out[l-1-i] = e } @@ -168,12 +159,12 @@ func Reverse[T any](s []T) (out []T) { } // Zip retourne une map dont les clés sont les valeurs du premier slice et les valeurs, les valeurs du second. -func Zip[K comparable, V any](s1 []K, s2 []V) (out map[K]V) { +func Zip[K comparable, V any, SK ~[]K, SV ~[]V](keys SK, values SV) (out map[K]V) { out = make(map[K]V) - l := min(len(s1), len(s2)) + l := min(len(keys), len(values)) - for i, k := range s1[:l] { - out[k] = s2[i] + for i, k := range keys[:l] { + out[k] = values[i] } return @@ -190,16 +181,6 @@ func Unzip[K comparable, V any](m map[K]V) (keys []K, values []V) { } // Equal retourne vrai si les slices sont identiques. -func Equal[T comparable](sl1, sl2 []T) bool { - if len(sl1) != len(sl2) { - return false - } - - for i, e1 := range sl1 { - if e1 != sl2[i] { - return false - } - } - - return true +func Equal[T comparable, S ~[]T](s1, s2 S) bool { + return slices.Equal(s1, s2) }