Corrections module collection

This commit is contained in:
Benjamin VAUDOUR 2024-03-03 09:06:29 +01:00
parent 3307dec97c
commit c473e663e8
1 changed files with 43 additions and 62 deletions

View File

@ -1,5 +1,9 @@
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))
@ -12,41 +16,34 @@ func Slice[T any](in ...T) (out []any) {
}
// Add ajoute les valeurs dentré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 dentré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 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) {
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 nexistent 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 nexistent 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 nexistent 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 dentré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 dentré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 dentré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 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))
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 lordre 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)
}