feat: sher 包增加部分转换和去重相关函数
This commit is contained in:
parent
3e41068619
commit
2ff360c48c
|
@ -452,7 +452,7 @@ func (srv *Server) low(message *Message, present time.Time, expect time.Duration
|
|||
fields = append(fields, log.String("type", messageNames[message.t]), log.String("cost", cost.String()), log.String("message", message.String()))
|
||||
fields = append(fields, message.marks...)
|
||||
//fields = append(fields, log.Stack("stack"))
|
||||
log.Warn("ServerLowMessage", sher.SliceCastToAny(fields)...)
|
||||
log.Warn("ServerLowMessage", sher.ConvertSliceToAny(fields)...)
|
||||
srv.OnMessageLowExecEvent(message, cost)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package sher
|
||||
|
||||
// SliceCastToAny 将切片转换为任意类型的切片
|
||||
func SliceCastToAny[S ~[]V, V any](s S) []any {
|
||||
var r = make([]any, len(s))
|
||||
for i, v := range s {
|
||||
r[i] = v
|
||||
}
|
||||
return r
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package sher
|
||||
|
||||
// ConvertSliceToAny 将切片转换为任意类型的切片
|
||||
func ConvertSliceToAny[S ~[]V, V any](s S) []any {
|
||||
var r = make([]any, len(s))
|
||||
for i, v := range s {
|
||||
r[i] = v
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ConvertSliceToIndexMap 将切片转换为索引为键的映射
|
||||
func ConvertSliceToIndexMap[S ~[]V, V any](s S) map[int]V {
|
||||
var r = make(map[int]V, len(s))
|
||||
for i, v := range s {
|
||||
r[i] = v
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ConvertSliceToMap 将切片转换为值为键的映射
|
||||
func ConvertSliceToMap[S ~[]V, V comparable](s S) map[V]struct{} {
|
||||
var r = make(map[V]struct{}, len(s))
|
||||
for _, v := range s {
|
||||
r[v] = struct{}{}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ConvertSliceToBoolMap 将切片转换为值为键的映射
|
||||
func ConvertSliceToBoolMap[S ~[]V, V comparable](s S) map[V]bool {
|
||||
var r = make(map[V]bool, len(s))
|
||||
for _, v := range s {
|
||||
r[v] = true
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ConvertMapKeysToSlice 将映射的键转换为切片
|
||||
func ConvertMapKeysToSlice[M ~map[K]V, K comparable, V any](m M) []K {
|
||||
var r = make([]K, 0, len(m))
|
||||
for k := range m {
|
||||
r = append(r, k)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ConvertMapValuesToSlice 将映射的值转换为切片
|
||||
func ConvertMapValuesToSlice[M ~map[K]V, K comparable, V any](m M) []V {
|
||||
var r = make([]V, 0, len(m))
|
||||
for _, v := range m {
|
||||
r = append(r, v)
|
||||
}
|
||||
return r
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package sher
|
||||
|
||||
// DeduplicateSliceInPlace 去除切片中的重复元素
|
||||
func DeduplicateSliceInPlace[S ~[]V, V comparable](s *S) {
|
||||
if s == nil || len(*s) < 2 {
|
||||
return
|
||||
}
|
||||
|
||||
var m = make(map[V]struct{}, len(*s))
|
||||
var writeIndex int
|
||||
for readIndex, v := range *s {
|
||||
if _, ok := m[v]; !ok {
|
||||
(*s)[writeIndex] = (*s)[readIndex]
|
||||
writeIndex++
|
||||
m[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
*s = (*s)[:writeIndex]
|
||||
}
|
||||
|
||||
// DeduplicateSlice 去除切片中的重复元素,返回新切片
|
||||
func DeduplicateSlice[S ~[]V, V comparable](s S) S {
|
||||
if s == nil || len(s) < 2 {
|
||||
return any(s).(S)
|
||||
}
|
||||
|
||||
var r = make([]V, 0, len(s))
|
||||
var m = make(map[V]struct{}, len(s))
|
||||
for _, v := range s {
|
||||
if _, ok := m[v]; !ok {
|
||||
r = append(r, v)
|
||||
m[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// DeduplicateSliceInPlaceWithCompare 去除切片中的重复元素,使用自定义的比较函数
|
||||
func DeduplicateSliceInPlaceWithCompare[S ~[]V, V any](s *S, compare func(a, b V) bool) {
|
||||
if s == nil || len(*s) < 2 {
|
||||
return
|
||||
}
|
||||
seen := make(map[int]struct{})
|
||||
resultIndex := 0
|
||||
for i := range *s {
|
||||
unique := true
|
||||
for j := range seen {
|
||||
if compare((*s)[i], (*s)[j]) {
|
||||
unique = false // Found a duplicate
|
||||
break
|
||||
}
|
||||
}
|
||||
if unique {
|
||||
seen[i] = struct{}{}
|
||||
(*s)[resultIndex] = (*s)[i]
|
||||
resultIndex++
|
||||
}
|
||||
}
|
||||
*s = (*s)[:resultIndex]
|
||||
}
|
||||
|
||||
// DeduplicateSliceWithCompare 去除切片中的重复元素,使用自定义的比较函数,返回新的切片
|
||||
func DeduplicateSliceWithCompare[S ~[]V, V any](s S, compare func(a, b V) bool) S {
|
||||
if s == nil || compare == nil || len(s) < 2 {
|
||||
return s
|
||||
}
|
||||
seen := make(map[int]struct{})
|
||||
var result = make([]V, 0, len(s))
|
||||
for i := range s {
|
||||
unique := true
|
||||
for j := range result {
|
||||
if compare(s[i], result[j]) {
|
||||
unique = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if unique {
|
||||
result = append(result, s[i])
|
||||
seen[i] = struct{}{}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package sher_test
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/sher"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeduplicateSliceInPlace(t *testing.T) {
|
||||
var cases = []struct {
|
||||
s []int
|
||||
expected []int
|
||||
}{
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
sher.DeduplicateSliceInPlace(&c.s)
|
||||
if len(c.s) != len(c.expected) {
|
||||
t.Errorf("DeduplicateSliceInPlace(%v) == %v, expected %v", c.s, c.s, c.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeduplicateSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
s []int
|
||||
expected []int
|
||||
}{
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
sl := len(c.s)
|
||||
if r := sher.DeduplicateSlice(c.s); len(r) != len(c.expected) || len(c.s) != sl {
|
||||
t.Errorf("DeduplicateSlice(%v) == %v, expected %v", c.s, r, c.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeduplicateSliceInPlaceWithCompare(t *testing.T) {
|
||||
var cases = []struct {
|
||||
s []int
|
||||
expected []int
|
||||
}{
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
sher.DeduplicateSliceInPlaceWithCompare(&c.s, func(a, b int) bool {
|
||||
return a == b
|
||||
})
|
||||
if len(c.s) != len(c.expected) {
|
||||
t.Errorf("DeduplicateSliceInPlaceWithCompare(%v) == %v, expected %v", c.s, c.s, c.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeduplicateSliceWithCompare(t *testing.T) {
|
||||
var cases = []struct {
|
||||
s []int
|
||||
expected []int
|
||||
}{
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
s: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2},
|
||||
expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
sl := len(c.s)
|
||||
if r := sher.DeduplicateSliceWithCompare(c.s, func(a, b int) bool {
|
||||
return a == b
|
||||
}); len(r) != len(c.expected) || len(c.s) != sl {
|
||||
t.Errorf("DeduplicateSliceWithCompare(%v) == %v, expected %v", c.s, r, c.expected)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue