@ -7,6 +7,8 @@ package set
import (
import (
"encoding/json"
"encoding/json"
"maps"
"maps"
"reflect"
"sort"
)
)
// Set is a set of T.
// Set is a set of T.
@ -53,16 +55,53 @@ func (s *Set[T]) Make() {
}
}
}
}
// Slice returns the elements of the set as a slice. The elements will not be
// Slice returns the elements of the set as a slice. If the element type is
// in any particular order.
// ordered (integers, floats, or strings), the elements are returned in sorted
// order. Otherwise, the order is not defined.
func ( s Set [ T ] ) Slice ( ) [ ] T {
func ( s Set [ T ] ) Slice ( ) [ ] T {
es := make ( [ ] T , 0 , s . Len ( ) )
es := make ( [ ] T , 0 , s . Len ( ) )
for k := range s {
for k := range s {
es = append ( es , k )
es = append ( es , k )
}
}
if f := genOrderedSwapper ( reflect . TypeFor [ T ] ( ) ) ; f != nil {
sort . Slice ( es , f ( reflect . ValueOf ( es ) ) )
}
return es
return es
}
}
// genOrderedSwapper returns a generator for a swap function that can be used to
// sort a slice of the given type. If rt is not an ordered type,
// genOrderedSwapper returns nil.
func genOrderedSwapper ( rt reflect . Type ) func ( reflect . Value ) func ( i , j int ) bool {
switch rt . Kind ( ) {
case reflect . Uint , reflect . Uint8 , reflect . Uint16 , reflect . Uint32 , reflect . Uint64 , reflect . Uintptr :
return func ( rv reflect . Value ) func ( i , j int ) bool {
return func ( i , j int ) bool {
return rv . Index ( i ) . Uint ( ) < rv . Index ( j ) . Uint ( )
}
}
case reflect . Int , reflect . Int8 , reflect . Int16 , reflect . Int32 , reflect . Int64 :
return func ( rv reflect . Value ) func ( i , j int ) bool {
return func ( i , j int ) bool {
return rv . Index ( i ) . Int ( ) < rv . Index ( j ) . Int ( )
}
}
case reflect . Float32 , reflect . Float64 :
return func ( rv reflect . Value ) func ( i , j int ) bool {
return func ( i , j int ) bool {
return rv . Index ( i ) . Float ( ) < rv . Index ( j ) . Float ( )
}
}
case reflect . String :
return func ( rv reflect . Value ) func ( i , j int ) bool {
return func ( i , j int ) bool {
return rv . Index ( i ) . String ( ) < rv . Index ( j ) . String ( )
}
}
}
return nil
}
// Delete removes e from the set.
// Delete removes e from the set.
func ( s Set [ T ] ) Delete ( e T ) { delete ( s , e ) }
func ( s Set [ T ] ) Delete ( e T ) { delete ( s , e ) }