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)) for i, e := range in { out[i] = e } return } // Add ajoute les valeurs d’entrée en fin du slice. 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](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](s *S, i int, in ...T) { if i <= 0 { Insert(s, in...) } else if i >= len(*s) { Add(s, in...) } else { *s = slices.Insert(*s, i, in...) } } // Diff retourne un slice contenant les entrées de s1 qui ne sont pas dans s2. func Diff[T comparable, S ~[]T](in1, in2 S) (out S) { ss := NewSet(in2...) for _, e := range in1 { if !ss.Contains(e) { Add(&out, e) } } return } // Intersect retourne un slice contenant les entrées contenues à la fois dans s1 et s2. func Intersect[T comparable, S ~[]T](in1, in2 S) (out S) { ss := NewSet(in2...) for _, e := range in1 { if ss.Contains(e) { Add(&out, e) } } return } // Uniq supprime les valeurs redondantes du slice. func Uniq[T comparable, S ~[]T](in S) (out S) { ss := NewSet[T]() for _, e := range in { if !ss.Contains(e) { ss.Add(e) Add(&out, e) } } return } // AddUniq ajoute les entrées en fin de slice si elles n’existent pas dans le slice. 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](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](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](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](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](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, S1 ~[]T1, S2 ~[]T2](in S1, f func(T1) T2) (out S2) { out = make(S2, len(in)) for i, e := range in { out[i] = f(e) } return } // Filter retourne un nouveau slice dont les valeurs passent la fonction. func Filter[T any, S ~[]T](in S, f func(T) bool) (out S) { for _, e := range in { if f(e) { Add(&out, e) } } return } // Reduce applique une fonction à tous les éléments dont le résultat sert à la prochaine itération. 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 in { out = f(out, e) } return } // Reverse inverse l’ordre du slice. 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 } return } // 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, SK ~[]K, SV ~[]V](keys SK, values SV) (out map[K]V) { out = make(map[K]V) l := min(len(keys), len(values)) for i, k := range keys[:l] { out[k] = values[i] } return } // Unzip sépare les clés et les valeurs de la map en 2 slices distincts. func Unzip[K comparable, V any](m map[K]V) (keys []K, values []V) { for k, v := range m { Add(&keys, k) Add(&values, v) } return } // Equal retourne vrai si les slices sont identiques. func Equal[T comparable, S ~[]T](s1, s2 S) bool { return slices.Equal(s1, s2) }