gob/collection/slice.go

206 lines
4.3 KiB
Go
Raw 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
// 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), in ...T) {
*s = append(*s, in...)
}
// Insert ajoute les valeurs dentrée en début du slice.
func Insert[T any](s *([]T), in ...T) {
*s = append(in, (*s)...)
}
// 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), i int, in ...T) {
if i <= 0 {
Insert(s, in...)
return
} else if i >= len(*s) {
Add(s, in...)
return
}
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...)
for _, e := range s1 {
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](s1, s2 []T) (out []T) {
ss := NewSet(s2...)
for _, e := range s1 {
if ss.Contains(e) {
Add(&out, e)
}
}
return
}
// Uniq supprime les valeurs redondantes du slice.
func Uniq[T comparable](s []T) (out []T) {
ss := NewSet[T]()
for _, e := range s {
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), 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), 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), 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, in T) bool {
for _, e := range s {
if e == in {
return true
}
}
return false
}
// ContainsOneOf retourne vrai si le slice contient une des valeurs dentrée.
func ContainsOneOf[T comparable](s []T, 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, 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](s []T1, f func(T1) T2) (out []T2) {
out = make([]T2, len(s))
for i, e := range s {
out[i] = f(e)
}
return
}
// 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 {
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, f func(T, T) T, initial ...T) (out T) {
if len(initial) > 0 {
out = initial[0]
}
for _, e := range s {
out = f(out, e)
}
return
}
// Reverse inverse lordre du slice.
func Reverse[T any](s []T) (out []T) {
l := len(s)
out = make([]T, l)
for i, e := range s {
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](s1 []K, s2 []V) (out map[K]V) {
out = make(map[K]V)
l := min(len(s1), len(s2))
for i, k := range s1[:l] {
out[k] = s2[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](sl1, sl2 []T) bool {
if len(sl1) != len(sl2) {
return false
}
for i, e1 := range sl1 {
if e1 != sl2[i] {
return false
}
}
return true
}