test: collection 包完善测试用例
This commit is contained in:
parent
66d903474d
commit
e3d966e215
|
@ -3,7 +3,7 @@ package activity
|
|||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/utils/collection"
|
||||
listings2 "github.com/kercylan98/minotaur/utils/collection/listings"
|
||||
"github.com/kercylan98/minotaur/utils/collection/listings"
|
||||
"github.com/kercylan98/minotaur/utils/generic"
|
||||
"github.com/kercylan98/minotaur/utils/log"
|
||||
"github.com/kercylan98/minotaur/utils/timer"
|
||||
|
@ -22,28 +22,28 @@ type (
|
|||
)
|
||||
|
||||
var (
|
||||
upcomingEventHandlers map[any]*listings2.PrioritySlice[func(activityId any)] // 即将开始的活动事件处理器
|
||||
startedEventHandlers map[any]*listings2.PrioritySlice[func(activityId any)] // 活动开始事件处理器
|
||||
endedEventHandlers map[any]*listings2.PrioritySlice[func(activityId any)] // 活动结束事件处理器
|
||||
extShowStartedEventHandlers map[any]*listings2.PrioritySlice[func(activityId any)] // 活动结束后延长展示开始事件处理器
|
||||
extShowEndedEventHandlers map[any]*listings2.PrioritySlice[func(activityId any)] // 活动结束后延长展示结束事件处理器
|
||||
newDayEventHandlers map[any]*listings2.PrioritySlice[func(activityId any)] // 新的一天事件处理器
|
||||
upcomingEventHandlers map[any]*listings.PrioritySlice[func(activityId any)] // 即将开始的活动事件处理器
|
||||
startedEventHandlers map[any]*listings.PrioritySlice[func(activityId any)] // 活动开始事件处理器
|
||||
endedEventHandlers map[any]*listings.PrioritySlice[func(activityId any)] // 活动结束事件处理器
|
||||
extShowStartedEventHandlers map[any]*listings.PrioritySlice[func(activityId any)] // 活动结束后延长展示开始事件处理器
|
||||
extShowEndedEventHandlers map[any]*listings.PrioritySlice[func(activityId any)] // 活动结束后延长展示结束事件处理器
|
||||
newDayEventHandlers map[any]*listings.PrioritySlice[func(activityId any)] // 新的一天事件处理器
|
||||
)
|
||||
|
||||
func init() {
|
||||
upcomingEventHandlers = make(map[any]*listings2.PrioritySlice[func(activityId any)])
|
||||
startedEventHandlers = make(map[any]*listings2.PrioritySlice[func(activityId any)])
|
||||
endedEventHandlers = make(map[any]*listings2.PrioritySlice[func(activityId any)])
|
||||
extShowStartedEventHandlers = make(map[any]*listings2.PrioritySlice[func(activityId any)])
|
||||
extShowEndedEventHandlers = make(map[any]*listings2.PrioritySlice[func(activityId any)])
|
||||
newDayEventHandlers = make(map[any]*listings2.PrioritySlice[func(activityId any)])
|
||||
upcomingEventHandlers = make(map[any]*listings.PrioritySlice[func(activityId any)])
|
||||
startedEventHandlers = make(map[any]*listings.PrioritySlice[func(activityId any)])
|
||||
endedEventHandlers = make(map[any]*listings.PrioritySlice[func(activityId any)])
|
||||
extShowStartedEventHandlers = make(map[any]*listings.PrioritySlice[func(activityId any)])
|
||||
extShowEndedEventHandlers = make(map[any]*listings.PrioritySlice[func(activityId any)])
|
||||
newDayEventHandlers = make(map[any]*listings.PrioritySlice[func(activityId any)])
|
||||
}
|
||||
|
||||
// RegUpcomingEvent 注册即将开始的活动事件处理器
|
||||
func RegUpcomingEvent[Type, ID generic.Basic](activityType Type, handler UpcomingEventHandler[ID], priority ...int) {
|
||||
handlers, exist := upcomingEventHandlers[activityType]
|
||||
if !exist {
|
||||
handlers = listings2.NewPrioritySlice[func(activityId any)]()
|
||||
handlers = listings.NewPrioritySlice[func(activityId any)]()
|
||||
upcomingEventHandlers[activityType] = handlers
|
||||
}
|
||||
handlers.Append(func(activityId any) {
|
||||
|
@ -76,7 +76,7 @@ func OnUpcomingEvent[Type, ID generic.Basic](activity *Activity[Type, ID]) {
|
|||
func RegStartedEvent[Type, ID generic.Basic](activityType Type, handler StartedEventHandler[ID], priority ...int) {
|
||||
handlers, exist := startedEventHandlers[activityType]
|
||||
if !exist {
|
||||
handlers = listings2.NewPrioritySlice[func(activityId any)]()
|
||||
handlers = listings.NewPrioritySlice[func(activityId any)]()
|
||||
startedEventHandlers[activityType] = handlers
|
||||
}
|
||||
handlers.Append(func(activityId any) {
|
||||
|
@ -117,7 +117,7 @@ func OnStartedEvent[Type, ID generic.Basic](activity *Activity[Type, ID]) {
|
|||
func RegEndedEvent[Type, ID generic.Basic](activityType Type, handler EndedEventHandler[ID], priority ...int) {
|
||||
handlers, exist := endedEventHandlers[activityType]
|
||||
if !exist {
|
||||
handlers = listings2.NewPrioritySlice[func(activityId any)]()
|
||||
handlers = listings.NewPrioritySlice[func(activityId any)]()
|
||||
endedEventHandlers[activityType] = handlers
|
||||
}
|
||||
handlers.Append(func(activityId any) {
|
||||
|
@ -150,7 +150,7 @@ func OnEndedEvent[Type, ID generic.Basic](activity *Activity[Type, ID]) {
|
|||
func RegExtendedShowStartedEvent[Type, ID generic.Basic](activityType Type, handler ExtendedShowStartedEventHandler[ID], priority ...int) {
|
||||
handlers, exist := extShowStartedEventHandlers[activityType]
|
||||
if !exist {
|
||||
handlers = listings2.NewPrioritySlice[func(activityId any)]()
|
||||
handlers = listings.NewPrioritySlice[func(activityId any)]()
|
||||
extShowStartedEventHandlers[activityType] = handlers
|
||||
}
|
||||
handlers.Append(func(activityId any) {
|
||||
|
@ -183,7 +183,7 @@ func OnExtendedShowStartedEvent[Type, ID generic.Basic](activity *Activity[Type,
|
|||
func RegExtendedShowEndedEvent[Type, ID generic.Basic](activityType Type, handler ExtendedShowEndedEventHandler[ID], priority ...int) {
|
||||
handlers, exist := extShowEndedEventHandlers[activityType]
|
||||
if !exist {
|
||||
handlers = listings2.NewPrioritySlice[func(activityId any)]()
|
||||
handlers = listings.NewPrioritySlice[func(activityId any)]()
|
||||
extShowEndedEventHandlers[activityType] = handlers
|
||||
}
|
||||
handlers.Append(func(activityId any) {
|
||||
|
@ -216,7 +216,7 @@ func OnExtendedShowEndedEvent[Type, ID generic.Basic](activity *Activity[Type, I
|
|||
func RegNewDayEvent[Type, ID generic.Basic](activityType Type, handler NewDayEventHandler[ID], priority ...int) {
|
||||
handlers, exist := newDayEventHandlers[activityType]
|
||||
if !exist {
|
||||
handlers = listings2.NewPrioritySlice[func(activityId any)]()
|
||||
handlers = listings.NewPrioritySlice[func(activityId any)]()
|
||||
newDayEventHandlers[activityType] = handlers
|
||||
}
|
||||
handlers.Append(func(activityId any) {
|
||||
|
|
|
@ -96,7 +96,7 @@ func (slf *TmplField) handleSlice(fieldName, fieldType string, fields map[string
|
|||
}
|
||||
slf.slice = true
|
||||
t := strings.TrimPrefix(fieldType, "[]")
|
||||
if collection.FindInMapKey(fields, t) {
|
||||
if collection.KeyInMap(fields, t) {
|
||||
slf.Struct = nil
|
||||
slf.Type = t
|
||||
} else {
|
||||
|
|
|
@ -19,7 +19,7 @@ func (slf *TmplStruct) addField(parent, name, desc, fieldType string, fields map
|
|||
Desc: desc,
|
||||
Type: fieldType,
|
||||
}
|
||||
if !collection.FindInMapKey(fields, fieldType) {
|
||||
if !collection.KeyInMap(fields, fieldType) {
|
||||
field.setStruct(parent, name, desc, fieldType, fields)
|
||||
} else {
|
||||
field.Type = GetFieldGolangType(fields[fieldType])
|
||||
|
|
|
@ -3,7 +3,7 @@ package server
|
|||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/utils/collection"
|
||||
listings2 "github.com/kercylan98/minotaur/utils/collection/listings"
|
||||
"github.com/kercylan98/minotaur/utils/collection/listings"
|
||||
"github.com/kercylan98/minotaur/utils/log"
|
||||
"github.com/kercylan98/minotaur/utils/runtimes"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
|
@ -43,45 +43,45 @@ type (
|
|||
func newEvent(srv *Server) *event {
|
||||
return &event{
|
||||
Server: srv,
|
||||
startBeforeEventHandlers: listings2.NewPrioritySlice[StartBeforeEventHandler](),
|
||||
startFinishEventHandlers: listings2.NewPrioritySlice[StartFinishEventHandler](),
|
||||
stopEventHandlers: listings2.NewPrioritySlice[StopEventHandler](),
|
||||
connectionReceivePacketEventHandlers: listings2.NewPrioritySlice[ConnectionReceivePacketEventHandler](),
|
||||
connectionOpenedEventHandlers: listings2.NewPrioritySlice[ConnectionOpenedEventHandler](),
|
||||
connectionClosedEventHandlers: listings2.NewPrioritySlice[ConnectionClosedEventHandler](),
|
||||
messageErrorEventHandlers: listings2.NewPrioritySlice[MessageErrorEventHandler](),
|
||||
messageLowExecEventHandlers: listings2.NewPrioritySlice[MessageLowExecEventHandler](),
|
||||
connectionOpenedAfterEventHandlers: listings2.NewPrioritySlice[ConnectionOpenedAfterEventHandler](),
|
||||
connectionWritePacketBeforeHandlers: listings2.NewPrioritySlice[ConnectionWritePacketBeforeEventHandler](),
|
||||
shuntChannelCreatedEventHandlers: listings2.NewPrioritySlice[ShuntChannelCreatedEventHandler](),
|
||||
shuntChannelClosedEventHandlers: listings2.NewPrioritySlice[ShuntChannelClosedEventHandler](),
|
||||
connectionPacketPreprocessEventHandlers: listings2.NewPrioritySlice[ConnectionPacketPreprocessEventHandler](),
|
||||
messageExecBeforeEventHandlers: listings2.NewPrioritySlice[MessageExecBeforeEventHandler](),
|
||||
messageReadyEventHandlers: listings2.NewPrioritySlice[MessageReadyEventHandler](),
|
||||
deadlockDetectEventHandlers: listings2.NewPrioritySlice[OnDeadlockDetectEventHandler](),
|
||||
startBeforeEventHandlers: listings.NewPrioritySlice[StartBeforeEventHandler](),
|
||||
startFinishEventHandlers: listings.NewPrioritySlice[StartFinishEventHandler](),
|
||||
stopEventHandlers: listings.NewPrioritySlice[StopEventHandler](),
|
||||
connectionReceivePacketEventHandlers: listings.NewPrioritySlice[ConnectionReceivePacketEventHandler](),
|
||||
connectionOpenedEventHandlers: listings.NewPrioritySlice[ConnectionOpenedEventHandler](),
|
||||
connectionClosedEventHandlers: listings.NewPrioritySlice[ConnectionClosedEventHandler](),
|
||||
messageErrorEventHandlers: listings.NewPrioritySlice[MessageErrorEventHandler](),
|
||||
messageLowExecEventHandlers: listings.NewPrioritySlice[MessageLowExecEventHandler](),
|
||||
connectionOpenedAfterEventHandlers: listings.NewPrioritySlice[ConnectionOpenedAfterEventHandler](),
|
||||
connectionWritePacketBeforeHandlers: listings.NewPrioritySlice[ConnectionWritePacketBeforeEventHandler](),
|
||||
shuntChannelCreatedEventHandlers: listings.NewPrioritySlice[ShuntChannelCreatedEventHandler](),
|
||||
shuntChannelClosedEventHandlers: listings.NewPrioritySlice[ShuntChannelClosedEventHandler](),
|
||||
connectionPacketPreprocessEventHandlers: listings.NewPrioritySlice[ConnectionPacketPreprocessEventHandler](),
|
||||
messageExecBeforeEventHandlers: listings.NewPrioritySlice[MessageExecBeforeEventHandler](),
|
||||
messageReadyEventHandlers: listings.NewPrioritySlice[MessageReadyEventHandler](),
|
||||
deadlockDetectEventHandlers: listings.NewPrioritySlice[OnDeadlockDetectEventHandler](),
|
||||
}
|
||||
}
|
||||
|
||||
type event struct {
|
||||
*Server
|
||||
startBeforeEventHandlers *listings2.PrioritySlice[StartBeforeEventHandler]
|
||||
startFinishEventHandlers *listings2.PrioritySlice[StartFinishEventHandler]
|
||||
stopEventHandlers *listings2.PrioritySlice[StopEventHandler]
|
||||
connectionReceivePacketEventHandlers *listings2.PrioritySlice[ConnectionReceivePacketEventHandler]
|
||||
connectionOpenedEventHandlers *listings2.PrioritySlice[ConnectionOpenedEventHandler]
|
||||
connectionClosedEventHandlers *listings2.PrioritySlice[ConnectionClosedEventHandler]
|
||||
messageErrorEventHandlers *listings2.PrioritySlice[MessageErrorEventHandler]
|
||||
messageLowExecEventHandlers *listings2.PrioritySlice[MessageLowExecEventHandler]
|
||||
connectionOpenedAfterEventHandlers *listings2.PrioritySlice[ConnectionOpenedAfterEventHandler]
|
||||
connectionWritePacketBeforeHandlers *listings2.PrioritySlice[ConnectionWritePacketBeforeEventHandler]
|
||||
shuntChannelCreatedEventHandlers *listings2.PrioritySlice[ShuntChannelCreatedEventHandler]
|
||||
shuntChannelClosedEventHandlers *listings2.PrioritySlice[ShuntChannelClosedEventHandler]
|
||||
connectionPacketPreprocessEventHandlers *listings2.PrioritySlice[ConnectionPacketPreprocessEventHandler]
|
||||
messageExecBeforeEventHandlers *listings2.PrioritySlice[MessageExecBeforeEventHandler]
|
||||
messageReadyEventHandlers *listings2.PrioritySlice[MessageReadyEventHandler]
|
||||
deadlockDetectEventHandlers *listings2.PrioritySlice[OnDeadlockDetectEventHandler]
|
||||
startBeforeEventHandlers *listings.PrioritySlice[StartBeforeEventHandler]
|
||||
startFinishEventHandlers *listings.PrioritySlice[StartFinishEventHandler]
|
||||
stopEventHandlers *listings.PrioritySlice[StopEventHandler]
|
||||
connectionReceivePacketEventHandlers *listings.PrioritySlice[ConnectionReceivePacketEventHandler]
|
||||
connectionOpenedEventHandlers *listings.PrioritySlice[ConnectionOpenedEventHandler]
|
||||
connectionClosedEventHandlers *listings.PrioritySlice[ConnectionClosedEventHandler]
|
||||
messageErrorEventHandlers *listings.PrioritySlice[MessageErrorEventHandler]
|
||||
messageLowExecEventHandlers *listings.PrioritySlice[MessageLowExecEventHandler]
|
||||
connectionOpenedAfterEventHandlers *listings.PrioritySlice[ConnectionOpenedAfterEventHandler]
|
||||
connectionWritePacketBeforeHandlers *listings.PrioritySlice[ConnectionWritePacketBeforeEventHandler]
|
||||
shuntChannelCreatedEventHandlers *listings.PrioritySlice[ShuntChannelCreatedEventHandler]
|
||||
shuntChannelClosedEventHandlers *listings.PrioritySlice[ShuntChannelClosedEventHandler]
|
||||
connectionPacketPreprocessEventHandlers *listings.PrioritySlice[ConnectionPacketPreprocessEventHandler]
|
||||
messageExecBeforeEventHandlers *listings.PrioritySlice[MessageExecBeforeEventHandler]
|
||||
messageReadyEventHandlers *listings.PrioritySlice[MessageReadyEventHandler]
|
||||
deadlockDetectEventHandlers *listings.PrioritySlice[OnDeadlockDetectEventHandler]
|
||||
|
||||
consoleCommandEventHandlers map[string]*listings2.PrioritySlice[ConsoleCommandEventHandler]
|
||||
consoleCommandEventHandlers map[string]*listings.PrioritySlice[ConsoleCommandEventHandler]
|
||||
consoleCommandEventHandlerInitOnce sync.Once
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ func (slf *event) RegConsoleCommandEvent(command string, handler ConsoleCommandE
|
|||
}
|
||||
|
||||
slf.consoleCommandEventHandlerInitOnce.Do(func() {
|
||||
slf.consoleCommandEventHandlers = map[string]*listings2.PrioritySlice[ConsoleCommandEventHandler]{}
|
||||
slf.consoleCommandEventHandlers = map[string]*listings.PrioritySlice[ConsoleCommandEventHandler]{}
|
||||
go func() {
|
||||
for {
|
||||
var input string
|
||||
|
@ -124,7 +124,7 @@ func (slf *event) RegConsoleCommandEvent(command string, handler ConsoleCommandE
|
|||
})
|
||||
list, exist := slf.consoleCommandEventHandlers[command]
|
||||
if !exist {
|
||||
list = listings2.NewPrioritySlice[ConsoleCommandEventHandler]()
|
||||
list = listings.NewPrioritySlice[ConsoleCommandEventHandler]()
|
||||
slf.consoleCommandEventHandlers[command] = list
|
||||
}
|
||||
list.Append(handler, collection.FindFirstOrDefaultInSlice(priority, 0))
|
||||
|
|
|
@ -3,7 +3,7 @@ package gateway
|
|||
import (
|
||||
"github.com/kercylan98/minotaur/server"
|
||||
"github.com/kercylan98/minotaur/utils/collection"
|
||||
listings2 "github.com/kercylan98/minotaur/utils/collection/listings"
|
||||
"github.com/kercylan98/minotaur/utils/collection/listings"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -17,22 +17,22 @@ type (
|
|||
|
||||
func newEvents() *events {
|
||||
return &events{
|
||||
connectionOpenedEventHandles: listings2.NewPrioritySlice[ConnectionOpenedEventHandle](),
|
||||
connectionClosedEventHandles: listings2.NewPrioritySlice[ConnectionClosedEventHandle](),
|
||||
connectionReceivePacketEventHandles: listings2.NewPrioritySlice[ConnectionReceivePacketEventHandle](),
|
||||
endpointConnectOpenedEventHandles: listings2.NewPrioritySlice[EndpointConnectOpenedEventHandle](),
|
||||
endpointConnectClosedEventHandles: listings2.NewPrioritySlice[EndpointConnectClosedEventHandle](),
|
||||
endpointConnectReceivePacketEventHandles: listings2.NewPrioritySlice[EndpointConnectReceivePacketEventHandle](),
|
||||
connectionOpenedEventHandles: listings.NewPrioritySlice[ConnectionOpenedEventHandle](),
|
||||
connectionClosedEventHandles: listings.NewPrioritySlice[ConnectionClosedEventHandle](),
|
||||
connectionReceivePacketEventHandles: listings.NewPrioritySlice[ConnectionReceivePacketEventHandle](),
|
||||
endpointConnectOpenedEventHandles: listings.NewPrioritySlice[EndpointConnectOpenedEventHandle](),
|
||||
endpointConnectClosedEventHandles: listings.NewPrioritySlice[EndpointConnectClosedEventHandle](),
|
||||
endpointConnectReceivePacketEventHandles: listings.NewPrioritySlice[EndpointConnectReceivePacketEventHandle](),
|
||||
}
|
||||
}
|
||||
|
||||
type events struct {
|
||||
connectionOpenedEventHandles *listings2.PrioritySlice[ConnectionOpenedEventHandle]
|
||||
connectionClosedEventHandles *listings2.PrioritySlice[ConnectionClosedEventHandle]
|
||||
connectionReceivePacketEventHandles *listings2.PrioritySlice[ConnectionReceivePacketEventHandle]
|
||||
endpointConnectOpenedEventHandles *listings2.PrioritySlice[EndpointConnectOpenedEventHandle]
|
||||
endpointConnectClosedEventHandles *listings2.PrioritySlice[EndpointConnectClosedEventHandle]
|
||||
endpointConnectReceivePacketEventHandles *listings2.PrioritySlice[EndpointConnectReceivePacketEventHandle]
|
||||
connectionOpenedEventHandles *listings.PrioritySlice[ConnectionOpenedEventHandle]
|
||||
connectionClosedEventHandles *listings.PrioritySlice[ConnectionClosedEventHandle]
|
||||
connectionReceivePacketEventHandles *listings.PrioritySlice[ConnectionReceivePacketEventHandle]
|
||||
endpointConnectOpenedEventHandles *listings.PrioritySlice[EndpointConnectOpenedEventHandle]
|
||||
endpointConnectClosedEventHandles *listings.PrioritySlice[EndpointConnectClosedEventHandle]
|
||||
endpointConnectReceivePacketEventHandles *listings.PrioritySlice[EndpointConnectReceivePacketEventHandle]
|
||||
}
|
||||
|
||||
// RegConnectionOpenedEventHandle 注册客户端连接打开事件处理函数
|
||||
|
|
|
@ -70,7 +70,7 @@ type (
|
|||
|
||||
// HasMessageType 检查是否存在指定的消息类型
|
||||
func HasMessageType(mt MessageType) bool {
|
||||
return collection.FindInMapKey(messageNames, mt)
|
||||
return collection.KeyInMap(messageNames, mt)
|
||||
}
|
||||
|
||||
// Message 服务器消息
|
||||
|
|
|
@ -57,7 +57,7 @@ func GetNetworks() []Network {
|
|||
|
||||
// check 检查网络模式是否支持
|
||||
func (n Network) check() {
|
||||
if !collection.FindInMapKey(networkNameMap, string(n)) {
|
||||
if !collection.KeyInMap(networkNameMap, string(n)) {
|
||||
panic(fmt.Errorf("unsupported network mode: %s", n))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ func (slf *Area[ID, AreaInfo]) IsAllow(item Item[ID]) (constraintErr error, conf
|
|||
|
||||
// IsConflict 检测一个成员是否会造成冲突
|
||||
func (slf *Area[ID, AreaInfo]) IsConflict(item Item[ID]) bool {
|
||||
if collection.FindInMapKey(slf.items, item.GetID()) {
|
||||
if collection.KeyInMap(slf.items, item.GetID()) {
|
||||
return false
|
||||
}
|
||||
for _, conflict := range slf.conflicts {
|
||||
|
@ -58,7 +58,7 @@ func (slf *Area[ID, AreaInfo]) IsConflict(item Item[ID]) bool {
|
|||
|
||||
// GetConflictItems 获取与一个成员产生冲突的所有其他成员
|
||||
func (slf *Area[ID, AreaInfo]) GetConflictItems(item Item[ID]) map[ID]Item[ID] {
|
||||
if collection.FindInMapKey(slf.items, item.GetID()) {
|
||||
if collection.KeyInMap(slf.items, item.GetID()) {
|
||||
return nil
|
||||
}
|
||||
var conflictItems map[ID]Item[ID]
|
||||
|
|
|
@ -32,7 +32,7 @@ func (slf *Editor[ID, AreaInfo]) RemoveAreaItem(area *Area[ID, AreaInfo], item I
|
|||
|
||||
// AddAreaItem 将一个成员添加到编排区域中,如果该成员已经存在于编排区域中,则不进行任何操作
|
||||
func (slf *Editor[ID, AreaInfo]) AddAreaItem(area *Area[ID, AreaInfo], item Item[ID]) {
|
||||
if collection.FindInMapKey(slf.falls, item.GetID()) {
|
||||
if collection.KeyInMap(slf.falls, item.GetID()) {
|
||||
return
|
||||
}
|
||||
area.items[item.GetID()] = item
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package collection
|
||||
|
||||
import "github.com/kercylan98/minotaur/utils/generic"
|
||||
|
||||
type ComparisonHandler[V any] func(source, target V) bool
|
||||
type OrderedValueGetter[V any, N generic.Ordered] func(v V) N
|
|
@ -1,7 +1,5 @@
|
|||
package collection
|
||||
|
||||
type ComparisonHandler[V any] func(source, target V) bool
|
||||
|
||||
// InSlice 检查 v 是否被包含在 slice 中,当 handler 返回 true 时,表示 v 和 slice 中的某个元素相匹配
|
||||
func InSlice[S ~[]V, V any](slice S, v V, handler ComparisonHandler[V]) bool {
|
||||
if len(slice) == 0 {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package collection
|
||||
|
||||
import "github.com/kercylan98/minotaur/utils/generic"
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/generic"
|
||||
)
|
||||
|
||||
// FindLoopedNextInSlice 返回 i 的下一个数组成员,当 i 达到数组长度时从 0 开始
|
||||
// - 当 i 为负数时将返回第一个元素
|
||||
|
@ -143,32 +145,42 @@ func FindIndexInComparableSlice[S ~[]V, V comparable](slice S, v V) int {
|
|||
return -1
|
||||
}
|
||||
|
||||
// FindInSliceByBinary 判断切片中是否存在某个元素,返回第一个匹配的索引和元素,不存在则索引返回 -1
|
||||
func FindInSliceByBinary[S ~[]V, V any](slice S, handler func(v V) bool) (i int, t V) {
|
||||
low := 0
|
||||
high := len(slice) - 1
|
||||
|
||||
for low <= high {
|
||||
mid := low + (high-low)/2
|
||||
if handler(slice[mid]) {
|
||||
return mid, slice[mid]
|
||||
} else if handler(slice[mid]) {
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1, t
|
||||
}
|
||||
|
||||
// FindMinimumInSlice 获取切片中的最小值
|
||||
func FindMinimumInSlice[S ~[]V, V generic.Number](slice S, handler ComparisonHandler[V]) (result V) {
|
||||
// FindMinimumInComparableSlice 获取切片中的最小值
|
||||
func FindMinimumInComparableSlice[S ~[]V, V generic.Ordered](slice S) (result V) {
|
||||
if len(slice) == 0 {
|
||||
return
|
||||
}
|
||||
result = slice[0]
|
||||
for i := 1; i < len(slice); i++ {
|
||||
if handler(slice[i], result) {
|
||||
if result > slice[i] {
|
||||
result = slice[i]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMinimumInSlice 获取切片中的最小值
|
||||
func FindMinimumInSlice[S ~[]V, V any, N generic.Ordered](slice S, handler OrderedValueGetter[V, N]) (result V) {
|
||||
if len(slice) == 0 {
|
||||
return
|
||||
}
|
||||
result = slice[0]
|
||||
for i := 1; i < len(slice); i++ {
|
||||
if handler(result) > handler(slice[i]) {
|
||||
result = slice[i]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMaximumInComparableSlice 获取切片中的最大值
|
||||
func FindMaximumInComparableSlice[S ~[]V, V generic.Ordered](slice S) (result V) {
|
||||
if len(slice) == 0 {
|
||||
return
|
||||
}
|
||||
result = slice[0]
|
||||
for i := 1; i < len(slice); i++ {
|
||||
if result < slice[i] {
|
||||
result = slice[i]
|
||||
}
|
||||
}
|
||||
|
@ -176,44 +188,100 @@ func FindMinimumInSlice[S ~[]V, V generic.Number](slice S, handler ComparisonHan
|
|||
}
|
||||
|
||||
// FindMaximumInSlice 获取切片中的最大值
|
||||
func FindMaximumInSlice[S ~[]V, V generic.Number](slice S, handler ComparisonHandler[V]) (result V) {
|
||||
func FindMaximumInSlice[S ~[]V, V any, N generic.Ordered](slice S, handler OrderedValueGetter[V, N]) (result V) {
|
||||
if len(slice) == 0 {
|
||||
return
|
||||
}
|
||||
result = slice[0]
|
||||
for i := 1; i < len(slice); i++ {
|
||||
if handler(result, slice[i]) {
|
||||
if handler(result) < handler(slice[i]) {
|
||||
result = slice[i]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMin2MaxInSlice 获取切片中的最小值和最大值
|
||||
func FindMin2MaxInSlice[S ~[]V, V generic.Number](slice S, handler ComparisonHandler[V]) (min, max V) {
|
||||
// FindMin2MaxInComparableSlice 获取切片中的最小值和最大值
|
||||
func FindMin2MaxInComparableSlice[S ~[]V, V generic.Ordered](slice S) (min, max V) {
|
||||
if len(slice) == 0 {
|
||||
return
|
||||
}
|
||||
min = slice[0]
|
||||
max = slice[0]
|
||||
for i := 1; i < len(slice); i++ {
|
||||
if handler(slice[i], min) {
|
||||
if min > slice[i] {
|
||||
min = slice[i]
|
||||
}
|
||||
if handler(max, slice[i]) {
|
||||
if max < slice[i] {
|
||||
max = slice[i]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMin2MaxInSlice 获取切片中的最小值和最大值
|
||||
func FindMin2MaxInSlice[S ~[]V, V any, N generic.Ordered](slice S, handler OrderedValueGetter[V, N]) (min, max V) {
|
||||
if len(slice) == 0 {
|
||||
return
|
||||
}
|
||||
min = slice[0]
|
||||
max = slice[0]
|
||||
for i := 1; i < len(slice); i++ {
|
||||
if handler(min) > handler(slice[i]) {
|
||||
min = slice[i]
|
||||
}
|
||||
if handler(max) < handler(slice[i]) {
|
||||
max = slice[i]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMinFromComparableMap 获取 map 中的最小值
|
||||
func FindMinFromComparableMap[M ~map[K]V, K comparable, V generic.Ordered](m M) (result V) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
var first bool
|
||||
for _, v := range m {
|
||||
if !first {
|
||||
result = v
|
||||
first = true
|
||||
continue
|
||||
}
|
||||
if result > v {
|
||||
result = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMinFromMap 获取 map 中的最小值
|
||||
func FindMinFromMap[M ~map[K]V, K comparable, V generic.Number](m M, handler ComparisonHandler[V]) (result V) {
|
||||
func FindMinFromMap[M ~map[K]V, K comparable, V any, N generic.Ordered](m M, handler OrderedValueGetter[V, N]) (result V) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
var first bool
|
||||
for _, v := range m {
|
||||
if !first {
|
||||
result = v
|
||||
first = true
|
||||
continue
|
||||
}
|
||||
if handler(result) > handler(v) {
|
||||
result = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMaxFromComparableMap 获取 map 中的最大值
|
||||
func FindMaxFromComparableMap[M ~map[K]V, K comparable, V generic.Ordered](m M) (result V) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
for _, v := range m {
|
||||
if handler(v, result) {
|
||||
if result < v {
|
||||
result = v
|
||||
}
|
||||
}
|
||||
|
@ -221,36 +289,60 @@ func FindMinFromMap[M ~map[K]V, K comparable, V generic.Number](m M, handler Com
|
|||
}
|
||||
|
||||
// FindMaxFromMap 获取 map 中的最大值
|
||||
func FindMaxFromMap[M ~map[K]V, K comparable, V generic.Number](m M, handler ComparisonHandler[V]) (result V) {
|
||||
func FindMaxFromMap[M ~map[K]V, K comparable, V any, N generic.Ordered](m M, handler OrderedValueGetter[V, N]) (result V) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
for _, v := range m {
|
||||
if handler(result, v) {
|
||||
if handler(result) < handler(v) {
|
||||
result = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMin2MaxFromMap 获取 map 中的最小值和最大值
|
||||
func FindMin2MaxFromMap[M ~map[K]V, K comparable, V generic.Number](m M, handler ComparisonHandler[V]) (min, max V) {
|
||||
// FindMin2MaxFromComparableMap 获取 map 中的最小值和最大值
|
||||
func FindMin2MaxFromComparableMap[M ~map[K]V, K comparable, V generic.Ordered](m M) (min, max V) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
var first bool
|
||||
for _, v := range m {
|
||||
if handler(v, min) {
|
||||
if !first {
|
||||
min = v
|
||||
max = v
|
||||
first = true
|
||||
continue
|
||||
}
|
||||
if min > v {
|
||||
min = v
|
||||
}
|
||||
if handler(max, v) {
|
||||
if max < v {
|
||||
max = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindInMapKey 判断 map 中是否存在某个 key
|
||||
func FindInMapKey[M ~map[K]V, K comparable, V any](m M, k K) bool {
|
||||
_, exist := m[k]
|
||||
return exist
|
||||
// FindMin2MaxFromMap 获取 map 中的最小值和最大值
|
||||
func FindMin2MaxFromMap[M ~map[K]V, K comparable, V generic.Ordered](m M) (min, max V) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
var first bool
|
||||
for _, v := range m {
|
||||
if !first {
|
||||
min = v
|
||||
max = v
|
||||
first = true
|
||||
continue
|
||||
}
|
||||
if min > v {
|
||||
min = v
|
||||
}
|
||||
if max < v {
|
||||
max = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -48,3 +48,129 @@ func ExampleFindOrDefaultInComparableSlice() {
|
|||
// Output:
|
||||
// 2
|
||||
}
|
||||
|
||||
func ExampleFindInSlice() {
|
||||
_, result := collection.FindInSlice([]int{1, 2, 3}, func(v int) bool {
|
||||
return v == 2
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 2
|
||||
}
|
||||
|
||||
func ExampleFindIndexInSlice() {
|
||||
result := collection.FindIndexInSlice([]int{1, 2, 3}, func(v int) bool {
|
||||
return v == 2
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleFindInComparableSlice() {
|
||||
index, result := collection.FindInComparableSlice([]int{1, 2, 3}, 2)
|
||||
fmt.Println(index, result)
|
||||
// Output:
|
||||
// 1 2
|
||||
}
|
||||
|
||||
func ExampleFindIndexInComparableSlice() {
|
||||
result := collection.FindIndexInComparableSlice([]int{1, 2, 3}, 2)
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleFindMinimumInComparableSlice() {
|
||||
result := collection.FindMinimumInComparableSlice([]int{1, 2, 3})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleFindMinimumInSlice() {
|
||||
result := collection.FindMinimumInSlice([]int{1, 2, 3}, func(v int) int {
|
||||
return v
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleFindMaximumInComparableSlice() {
|
||||
result := collection.FindMaximumInComparableSlice([]int{1, 2, 3})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
|
||||
func ExampleFindMaximumInSlice() {
|
||||
result := collection.FindMaximumInSlice([]int{1, 2, 3}, func(v int) int {
|
||||
return v
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
|
||||
func ExampleFindMin2MaxInComparableSlice() {
|
||||
minimum, maximum := collection.FindMin2MaxInComparableSlice([]int{1, 2, 3})
|
||||
fmt.Println(minimum, maximum)
|
||||
// Output:
|
||||
// 1 3
|
||||
}
|
||||
|
||||
func ExampleFindMin2MaxInSlice() {
|
||||
minimum, maximum := collection.FindMin2MaxInSlice([]int{1, 2, 3}, func(v int) int {
|
||||
return v
|
||||
})
|
||||
fmt.Println(minimum, maximum)
|
||||
// Output:
|
||||
// 1 3
|
||||
}
|
||||
|
||||
func ExampleFindMinFromComparableMap() {
|
||||
result := collection.FindMinFromComparableMap(map[int]int{1: 1, 2: 2, 3: 3})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleFindMinFromMap() {
|
||||
result := collection.FindMinFromMap(map[int]int{1: 1, 2: 2, 3: 3}, func(v int) int {
|
||||
return v
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func ExampleFindMaxFromComparableMap() {
|
||||
result := collection.FindMaxFromComparableMap(map[int]int{1: 1, 2: 2, 3: 3})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
|
||||
func ExampleFindMaxFromMap() {
|
||||
result := collection.FindMaxFromMap(map[int]int{1: 1, 2: 2, 3: 3}, func(v int) int {
|
||||
return v
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 3
|
||||
}
|
||||
|
||||
func ExampleFindMin2MaxFromComparableMap() {
|
||||
minimum, maximum := collection.FindMin2MaxFromComparableMap(map[int]int{1: 1, 2: 2, 3: 3})
|
||||
fmt.Println(minimum, maximum)
|
||||
// Output:
|
||||
// 1 3
|
||||
}
|
||||
|
||||
func ExampleFindMin2MaxFromMap() {
|
||||
minimum, maximum := collection.FindMin2MaxFromMap(map[int]int{1: 1, 2: 2, 3: 3})
|
||||
fmt.Println(minimum, maximum)
|
||||
// Output:
|
||||
// 1 3
|
||||
}
|
||||
|
|
|
@ -127,3 +127,341 @@ func TestFindOrDefaultInComparableSlice(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindInSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindInSlice_NonEmptySlice", []int{1, 2, 3}, 2},
|
||||
{"TestFindInSlice_EmptySlice", []int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
_, actual := collection.FindInSlice(c.input, func(v int) bool {
|
||||
return v == 2
|
||||
})
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the element of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindIndexInSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindIndexInSlice_NonEmptySlice", []int{1, 2, 3}, 1},
|
||||
{"TestFindIndexInSlice_EmptySlice", []int{}, -1},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindIndexInSlice(c.input, func(v int) bool {
|
||||
return v == 2
|
||||
})
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the index of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindInComparableSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindInComparableSlice_NonEmptySlice", []int{1, 2, 3}, 2},
|
||||
{"TestFindInComparableSlice_EmptySlice", []int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
_, actual := collection.FindInComparableSlice(c.input, 2)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the element of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindIndexInComparableSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindIndexInComparableSlice_NonEmptySlice", []int{1, 2, 3}, 1},
|
||||
{"TestFindIndexInComparableSlice_EmptySlice", []int{}, -1},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindIndexInComparableSlice(c.input, 2)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the index of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMinimumInComparableSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMinimumInComparableSlice_NonEmptySlice", []int{1, 2, 3}, 1},
|
||||
{"TestFindMinimumInComparableSlice_EmptySlice", []int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMinimumInComparableSlice(c.input)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMinimumInSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMinimumInSlice_NonEmptySlice", []int{1, 2, 3}, 1},
|
||||
{"TestFindMinimumInSlice_EmptySlice", []int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMinimumInSlice(c.input, func(v int) int {
|
||||
return v
|
||||
})
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMaximumInComparableSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMaximumInComparableSlice_NonEmptySlice", []int{1, 2, 3}, 3},
|
||||
{"TestFindMaximumInComparableSlice_EmptySlice", []int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMaximumInComparableSlice(c.input)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the maximum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMaximumInSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMaximumInSlice_NonEmptySlice", []int{1, 2, 3}, 3},
|
||||
{"TestFindMaximumInSlice_EmptySlice", []int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMaximumInSlice(c.input, func(v int) int {
|
||||
return v
|
||||
})
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the maximum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMin2MaxInComparableSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expectedMin int
|
||||
expectedMax int
|
||||
}{
|
||||
{"TestFindMin2MaxInComparableSlice_NonEmptySlice", []int{1, 2, 3}, 1, 3},
|
||||
{"TestFindMin2MaxInComparableSlice_EmptySlice", []int{}, 0, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
minimum, maximum := collection.FindMin2MaxInComparableSlice(c.input)
|
||||
if minimum != c.expectedMin || maximum != c.expectedMax {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expectedMin, minimum, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMin2MaxInSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expectedMin int
|
||||
expectedMax int
|
||||
}{
|
||||
{"TestFindMin2MaxInSlice_NonEmptySlice", []int{1, 2, 3}, 1, 3},
|
||||
{"TestFindMin2MaxInSlice_EmptySlice", []int{}, 0, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
minimum, maximum := collection.FindMin2MaxInSlice(c.input, func(v int) int {
|
||||
return v
|
||||
})
|
||||
if minimum != c.expectedMin || maximum != c.expectedMax {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expectedMin, minimum, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMinFromComparableMap(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input map[int]int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMinFromComparableMap_NonEmptyMap", map[int]int{1: 1, 2: 2, 3: 3}, 1},
|
||||
{"TestFindMinFromComparableMap_EmptyMap", map[int]int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMinFromComparableMap(c.input)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMinFromMap(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input map[int]int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMinFromMap_NonEmptyMap", map[int]int{1: 1, 2: 2, 3: 3}, 1},
|
||||
{"TestFindMinFromMap_EmptyMap", map[int]int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMinFromMap(c.input, func(v int) int {
|
||||
return v
|
||||
})
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMaxFromComparableMap(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input map[int]int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMaxFromComparableMap_NonEmptyMap", map[int]int{1: 1, 2: 2, 3: 3}, 3},
|
||||
{"TestFindMaxFromComparableMap_EmptyMap", map[int]int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMaxFromComparableMap(c.input)
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the maximum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMaxFromMap(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input map[int]int
|
||||
expected int
|
||||
}{
|
||||
{"TestFindMaxFromMap_NonEmptyMap", map[int]int{1: 1, 2: 2, 3: 3}, 3},
|
||||
{"TestFindMaxFromMap_EmptyMap", map[int]int{}, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := collection.FindMaxFromMap(c.input, func(v int) int {
|
||||
return v
|
||||
})
|
||||
if actual != c.expected {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, actual, "the maximum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMin2MaxFromComparableMap(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input map[int]int
|
||||
expectedMin int
|
||||
expectedMax int
|
||||
}{
|
||||
{"TestFindMin2MaxFromComparableMap_NonEmptyMap", map[int]int{1: 1, 2: 2, 3: 3}, 1, 3},
|
||||
{"TestFindMin2MaxFromComparableMap_EmptyMap", map[int]int{}, 0, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
minimum, maximum := collection.FindMin2MaxFromComparableMap(c.input)
|
||||
if minimum != c.expectedMin || maximum != c.expectedMax {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expectedMin, minimum, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMin2MaxFromMap(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input map[int]int
|
||||
expectedMin int
|
||||
expectedMax int
|
||||
}{
|
||||
{"TestFindMin2MaxFromMap_NonEmptyMap", map[int]int{1: 1, 2: 2, 3: 3}, 1, 3},
|
||||
{"TestFindMin2MaxFromMap_EmptyMap", map[int]int{}, 0, 0},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
minimum, maximum := collection.FindMin2MaxFromMap(c.input)
|
||||
if minimum != c.expectedMin || maximum != c.expectedMax {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expectedMin, minimum, "the minimum of input is not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,5 +2,8 @@ package collection
|
|||
|
||||
// SwapSlice 将切片中的两个元素进行交换
|
||||
func SwapSlice[S ~[]V, V any](slice *S, i, j int) {
|
||||
if i < 0 || j < 0 || i >= len(*slice) || j >= len(*slice) {
|
||||
return
|
||||
}
|
||||
(*slice)[i], (*slice)[j] = (*slice)[j], (*slice)[i]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package collection_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/utils/collection"
|
||||
)
|
||||
|
||||
func ExampleSwapSlice() {
|
||||
var s = []int{1, 2, 3}
|
||||
collection.SwapSlice(&s, 0, 1)
|
||||
fmt.Println(s)
|
||||
// Output:
|
||||
// [2 1 3]
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package collection_test
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/collection"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSwapSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
slice []int
|
||||
i int
|
||||
j int
|
||||
expect []int
|
||||
}{
|
||||
{"TestSwapSliceNonEmpty", []int{1, 2, 3}, 0, 1, []int{2, 1, 3}},
|
||||
{"TestSwapSliceEmpty", []int{}, 0, 0, []int{}},
|
||||
{"TestSwapSliceIndexOutOfBound", []int{1, 2, 3}, 0, 3, []int{1, 2, 3}},
|
||||
{"TestSwapSliceNil", nil, 0, 0, nil},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
collection.SwapSlice(&c.slice, c.i, c.j)
|
||||
for i, v := range c.slice {
|
||||
if v != c.expect[i] {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expect, c.slice, "the slice is not equal")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package collection
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ExampleMappingFromSlice() {
|
||||
result := MappingFromSlice[[]int, []int]([]int{1, 2, 3}, func(value int) int {
|
||||
return value + 1
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// [2 3 4]
|
||||
}
|
||||
|
||||
func ExampleMappingFromMap() {
|
||||
result := MappingFromMap[map[int]int, map[int]int](map[int]int{1: 1, 2: 2, 3: 3}, func(value int) int {
|
||||
return value + 1
|
||||
})
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// map[1:2 2:3 3:4]
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package collection_test
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/collection"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMappingFromSlice(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input []int
|
||||
expected []int
|
||||
}{
|
||||
{"TestMappingFromSlice_NonEmptySlice", []int{1, 2, 3}, []int{2, 3, 4}},
|
||||
{"TestMappingFromSlice_EmptySlice", []int{}, []int{}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
result := collection.MappingFromSlice[[]int, []int](c.input, func(value int) int {
|
||||
return value + 1
|
||||
})
|
||||
if len(result) != len(c.expected) {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, result, "the length of input is not equal")
|
||||
}
|
||||
for i := 0; i < len(result); i++ {
|
||||
if result[i] != c.expected[i] {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, result, "the value of input is not equal")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingFromMap(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
input map[int]int
|
||||
expected map[int]int
|
||||
}{
|
||||
{"TestMappingFromMap_NonEmptyMap", map[int]int{1: 1, 2: 2, 3: 3}, map[int]int{1: 2, 2: 3, 3: 4}},
|
||||
{"TestMappingFromMap_EmptyMap", map[int]int{}, map[int]int{}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
result := collection.MappingFromMap[map[int]int, map[int]int](c.input, func(value int) int {
|
||||
return value + 1
|
||||
})
|
||||
if len(result) != len(c.expected) {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, result, "the length of input is not equal")
|
||||
}
|
||||
for k, v := range result {
|
||||
if v != c.expected[k] {
|
||||
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s", c.name, c.expected, result, "the value of input is not equal")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ type Deck[I Item] struct {
|
|||
|
||||
// AddGroup 将一个组添加到甲板中
|
||||
func (slf *Deck[I]) AddGroup(group *Group[I]) {
|
||||
if !collection.FindInMapKey(slf.groups, group.GetGuid()) {
|
||||
if !collection.KeyInMap(slf.groups, group.GetGuid()) {
|
||||
slf.groups[group.GetGuid()] = group
|
||||
slf.sort = append(slf.sort, group.GetGuid())
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func (slf *FSM[State, Data]) Unregister(state State) {
|
|||
|
||||
// HasState 检查状态机是否存在特定状态
|
||||
func (slf *FSM[State, Data]) HasState(state State) bool {
|
||||
return collection.FindInMapKey(slf.states, state)
|
||||
return collection.KeyInMap(slf.states, state)
|
||||
}
|
||||
|
||||
// Change 改变状态机状态到新的状态
|
||||
|
|
Loading…
Reference in New Issue