gob/collection/slice.go

187 lines
4.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package collection
import (
"slices"
)
// Slice crée un slice générique contenant les valeurs dentré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 dentrée en fin du slice.
func Add[T any, S ~[]T](s *S, in ...T) {
*s = append(*s, in...)
}
// Insert ajoute les valeurs dentré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 dentrée à lindex i du slice.
// - Si lindex est inférieur à 0, agit comme Insert.
// - Si lindex 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 nexistent 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 nexistent 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 nexistent 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 dentré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 dentré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 dentrée.
func ContainsAll[T comparable, S ~[]T](s S, in ...T) bool {
return NewSet(s...).ContainsAll(in...)
}
// Maps retourne un slice à partir dun 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 lordre 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)
}