From ed23499943ac4fcdcd7673a4a232e0e12ce8ea3c Mon Sep 17 00:00:00 2001 From: CHEN Feng Date: Sun, 7 Aug 2022 10:39:06 +0800 Subject: [PATCH] add Map interface (#44) --- README.md | 50 ++++++++++++++++++++++++++++++++++++------------ README_zh.md | 50 ++++++++++++++++++++++++++++++++++++------------ container.go | 11 +++++++++++ skiplist_test.go | 2 +- 4 files changed, 88 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 79b6712..5882a34 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Package stl4go is a generic container and algorithm library for go. - [type HashFn](<#type-hashfn>) - [type Integer](<#type-integer>) - [type LessFn](<#type-lessfn>) +- [type Map](<#type-map>) - [type Numeric](<#type-numeric>) - [type Ordered](<#type-ordered>) - [type Queue](<#type-queue>) @@ -127,6 +128,7 @@ Package stl4go is a generic container and algorithm library for go. - [type SkipList](<#type-skiplist>) - [func NewSkipList[K Ordered, V any]() *SkipList[K, V]](<#func-newskiplist>) - [func NewSkipListFromMap[K Ordered, V any](m map[K]V) *SkipList[K, V]](<#func-newskiplistfrommap>) + - [func NewSkipListFunc[K any, V any](keyCmp CompareFn[K]) *SkipList[K, V]](<#func-newskiplistfunc>) - [func (sl *SkipList[K, V]) Clear()](<#func-skiplistk-v-clear>) - [func (sl *SkipList[K, V]) Find(key K) *V](<#func-skiplistk-v-find>) - [func (sl *SkipList[K, V]) ForEach(op func(K, *V))](<#func-skiplistk-v-foreach>) @@ -839,6 +841,22 @@ LessFn is a function that returns whether 'a' is less than 'b'. type LessFn[T any] func(a, b T) bool ``` +## type [Map]() + +Map is a associative container that contains key\-value pairs with unique keys. + +```go +type Map[K any, V any] interface { + Container + Has(K) bool // Checks whether the container contains element with specific key. + Find(K) *V // Finds element with specific key. + Insert(K, V) // Inserts a key-value pair in to the container or replace existing value. + Remove(K) bool // Remove element with specific key. + ForEach(func(K, *V)) // Iterate the container. + ForEachIf(func(K, *V) bool) // Iterate the container, stops when the callback returns false. +} +``` + ## type [Numeric]() Numeric is a constraint that permits any numeric type. @@ -1030,7 +1048,7 @@ SkipList is a probabilistic data structure that seem likely to supplant balanced See https://en.wikipedia.org/wiki/Skip_list for more details. ```go -type SkipList[K Ordered, V any] struct { +type SkipList[K any, V any] struct { // contains filtered or unexported fields } ``` @@ -1041,9 +1059,9 @@ type SkipList[K Ordered, V any] struct { func NewSkipList[K Ordered, V any]() *SkipList[K, V] ``` -NewSkipList create a new Skiplist. +NewSkipList creates a new Skiplist. -### func [NewSkipListFromMap]() +### func [NewSkipListFromMap]() ```go func NewSkipListFromMap[K Ordered, V any](m map[K]V) *SkipList[K, V] @@ -1051,13 +1069,21 @@ func NewSkipListFromMap[K Ordered, V any](m map[K]V) *SkipList[K, V] NewSkipListFromMap create a new Skiplist from a map. -### func \(\*SkipList\[K, V\]\) [Clear]() +### func [NewSkipListFunc]() + +```go +func NewSkipListFunc[K any, V any](keyCmp CompareFn[K]) *SkipList[K, V] +``` + +NewSkipListFunc creates a new Skiplist with specified compare function keyCmp. + +### func \(\*SkipList\[K, V\]\) [Clear]() ```go func (sl *SkipList[K, V]) Clear() ``` -### func \(\*SkipList\[K, V\]\) [Find]() +### func \(\*SkipList\[K, V\]\) [Find]() ```go func (sl *SkipList[K, V]) Find(key K) *V @@ -1065,25 +1091,25 @@ func (sl *SkipList[K, V]) Find(key K) *V Find returns the value associated with the passed key if the key is in the skiplist, otherwise returns nil. -### func \(\*SkipList\[K, V\]\) [ForEach]() +### func \(\*SkipList\[K, V\]\) [ForEach]() ```go func (sl *SkipList[K, V]) ForEach(op func(K, *V)) ``` -### func \(\*SkipList\[K, V\]\) [ForEachIf]() +### func \(\*SkipList\[K, V\]\) [ForEachIf]() ```go func (sl *SkipList[K, V]) ForEachIf(op func(K, *V) bool) ``` -### func \(\*SkipList\[K, V\]\) [Has]() +### func \(\*SkipList\[K, V\]\) [Has]() ```go func (sl *SkipList[K, V]) Has(key K) bool ``` -### func \(\*SkipList\[K, V\]\) [Insert]() +### func \(\*SkipList\[K, V\]\) [Insert]() ```go func (sl *SkipList[K, V]) Insert(key K, value V) @@ -1091,19 +1117,19 @@ func (sl *SkipList[K, V]) Insert(key K, value V) Insert inserts a key\-value pair into the skiplist. If the key is already in the skip list, it's value will be updated. -### func \(\*SkipList\[K, V\]\) [IsEmpty]() +### func \(\*SkipList\[K, V\]\) [IsEmpty]() ```go func (sl *SkipList[K, V]) IsEmpty() bool ``` -### func \(\*SkipList\[K, V\]\) [Len]() +### func \(\*SkipList\[K, V\]\) [Len]() ```go func (sl *SkipList[K, V]) Len() int ``` -### func \(\*SkipList\[K, V\]\) [Remove]() +### func \(\*SkipList\[K, V\]\) [Remove]() ```go func (sl *SkipList[K, V]) Remove(key K) bool diff --git a/README_zh.md b/README_zh.md index 4842a67..3c1cbd5 100644 --- a/README_zh.md +++ b/README_zh.md @@ -93,6 +93,7 @@ Package stl4go is a generic container and algorithm library for go. - [type HashFn](<#type-hashfn>) - [type Integer](<#type-integer>) - [type LessFn](<#type-lessfn>) +- [type Map](<#type-map>) - [type Numeric](<#type-numeric>) - [type Ordered](<#type-ordered>) - [type Queue](<#type-queue>) @@ -123,6 +124,7 @@ Package stl4go is a generic container and algorithm library for go. - [type SkipList](<#type-skiplist>) - [func NewSkipList[K Ordered, V any]() *SkipList[K, V]](<#func-newskiplist>) - [func NewSkipListFromMap[K Ordered, V any](m map[K]V) *SkipList[K, V]](<#func-newskiplistfrommap>) + - [func NewSkipListFunc[K any, V any](keyCmp CompareFn[K]) *SkipList[K, V]](<#func-newskiplistfunc>) - [func (sl *SkipList[K, V]) Clear()](<#func-skiplistk-v-clear>) - [func (sl *SkipList[K, V]) Find(key K) *V](<#func-skiplistk-v-find>) - [func (sl *SkipList[K, V]) ForEach(op func(K, *V))](<#func-skiplistk-v-foreach>) @@ -835,6 +837,22 @@ LessFn is a function that returns whether 'a' is less than 'b'. type LessFn[T any] func(a, b T) bool ``` +## type [Map]() + +Map is a associative container that contains key\-value pairs with unique keys. + +```go +type Map[K any, V any] interface { + Container + Has(K) bool // Checks whether the container contains element with specific key. + Find(K) *V // Finds element with specific key. + Insert(K, V) // Inserts a key-value pair in to the container or replace existing value. + Remove(K) bool // Remove element with specific key. + ForEach(func(K, *V)) // Iterate the container. + ForEachIf(func(K, *V) bool) // Iterate the container, stops when the callback returns false. +} +``` + ## type [Numeric]() Numeric is a constraint that permits any numeric type. @@ -1026,7 +1044,7 @@ SkipList is a probabilistic data structure that seem likely to supplant balanced See https://en.wikipedia.org/wiki/Skip_list for more details. ```go -type SkipList[K Ordered, V any] struct { +type SkipList[K any, V any] struct { // contains filtered or unexported fields } ``` @@ -1037,9 +1055,9 @@ type SkipList[K Ordered, V any] struct { func NewSkipList[K Ordered, V any]() *SkipList[K, V] ``` -NewSkipList create a new Skiplist. +NewSkipList creates a new Skiplist. -### func [NewSkipListFromMap]() +### func [NewSkipListFromMap]() ```go func NewSkipListFromMap[K Ordered, V any](m map[K]V) *SkipList[K, V] @@ -1047,13 +1065,21 @@ func NewSkipListFromMap[K Ordered, V any](m map[K]V) *SkipList[K, V] NewSkipListFromMap create a new Skiplist from a map. -### func \(\*SkipList\[K, V\]\) [Clear]() +### func [NewSkipListFunc]() + +```go +func NewSkipListFunc[K any, V any](keyCmp CompareFn[K]) *SkipList[K, V] +``` + +NewSkipListFunc creates a new Skiplist with specified compare function keyCmp. + +### func \(\*SkipList\[K, V\]\) [Clear]() ```go func (sl *SkipList[K, V]) Clear() ``` -### func \(\*SkipList\[K, V\]\) [Find]() +### func \(\*SkipList\[K, V\]\) [Find]() ```go func (sl *SkipList[K, V]) Find(key K) *V @@ -1061,25 +1087,25 @@ func (sl *SkipList[K, V]) Find(key K) *V Find returns the value associated with the passed key if the key is in the skiplist, otherwise returns nil. -### func \(\*SkipList\[K, V\]\) [ForEach]() +### func \(\*SkipList\[K, V\]\) [ForEach]() ```go func (sl *SkipList[K, V]) ForEach(op func(K, *V)) ``` -### func \(\*SkipList\[K, V\]\) [ForEachIf]() +### func \(\*SkipList\[K, V\]\) [ForEachIf]() ```go func (sl *SkipList[K, V]) ForEachIf(op func(K, *V) bool) ``` -### func \(\*SkipList\[K, V\]\) [Has]() +### func \(\*SkipList\[K, V\]\) [Has]() ```go func (sl *SkipList[K, V]) Has(key K) bool ``` -### func \(\*SkipList\[K, V\]\) [Insert]() +### func \(\*SkipList\[K, V\]\) [Insert]() ```go func (sl *SkipList[K, V]) Insert(key K, value V) @@ -1087,19 +1113,19 @@ func (sl *SkipList[K, V]) Insert(key K, value V) Insert inserts a key\-value pair into the skiplist. If the key is already in the skip list, it's value will be updated. -### func \(\*SkipList\[K, V\]\) [IsEmpty]() +### func \(\*SkipList\[K, V\]\) [IsEmpty]() ```go func (sl *SkipList[K, V]) IsEmpty() bool ``` -### func \(\*SkipList\[K, V\]\) [Len]() +### func \(\*SkipList\[K, V\]\) [Len]() ```go func (sl *SkipList[K, V]) Len() int ``` -### func \(\*SkipList\[K, V\]\) [Remove]() +### func \(\*SkipList\[K, V\]\) [Remove]() ```go func (sl *SkipList[K, V]) Remove(key K) bool diff --git a/container.go b/container.go index 6c08506..93cc138 100644 --- a/container.go +++ b/container.go @@ -6,3 +6,14 @@ type Container interface { Len() int // Len returns the number of elements in the container. Clear() // Clear erases all elements from the container. After this call, Len() returns zero. } + +// Map is a associative container that contains key-value pairs with unique keys. +type Map[K any, V any] interface { + Container + Has(K) bool // Checks whether the container contains element with specific key. + Find(K) *V // Finds element with specific key. + Insert(K, V) // Inserts a key-value pair in to the container or replace existing value. + Remove(K) bool // Remove element with specific key. + ForEach(func(K, *V)) // Iterate the container. + ForEachIf(func(K, *V) bool) // Iterate the container, stops when the callback returns false. +} diff --git a/skiplist_test.go b/skiplist_test.go index c836e5a..e03e3db 100644 --- a/skiplist_test.go +++ b/skiplist_test.go @@ -6,7 +6,7 @@ import ( ) func TestSkipListInterface(t *testing.T) { - _ = Container(NewSkipList[int, int]()) + _ = Map[int, int](NewSkipList[int, int]()) } func TestNewSkipList(t *testing.T) {