Added OrderedMap and Range types.

This commit is contained in:
Andrey Parhomenko 2023-07-09 11:39:35 +03:00
parent f51a8ab74b
commit 6afcd4e5e5
10 changed files with 192 additions and 42 deletions

2
go.mod
View file

@ -1,4 +1,4 @@
module github.com/surdeus/godat
module github.com/mojosa-software/godat
go 1.19

View file

@ -1,7 +1,7 @@
package main
import (
"github.com/surdeus/godat/src/sparsex"
"github.com/mojosa-software/godat/src/sparsex"
"fmt"
)

View file

@ -1,9 +1,10 @@
package main
import (
"github.com/surdeus/godat/src/mapx"
"github.com/surdeus/godat/src/slicex"
"github.com/surdeus/godat/src/poolx"
//"github.com/mojosa-software/godat/src/mapx"
//"github.com/mojosa-software/godat/src/slicex"
//"github.com/mojosa-software/godat/src/poolx"
"github.com/mojosa-software/godat/src/rangex"
"fmt"
)
@ -13,7 +14,13 @@ type Struct struct {
}
func main() {
m := map[string] string {
rangex.New[float32](0, .001, 1).Chan().ForEach(
func(i int, v float32) bool {
fmt.Println(i, v)
return true
},
)
/*m := map[string] string {
"Key1" : "Value1",
"Key2" : "Value2",
"Key3" : "Value3",
@ -49,5 +56,5 @@ func main() {
ll.Del(1)
for p := range ll.Range() {
fmt.Println(p)
}
}*/
}

20
src/iterx/iter.go Normal file
View file

@ -0,0 +1,20 @@
package iterx
// Implementing the interface lets us iterate through the
// the data by lightweight channels.
type Channeler[K any, V any] interface {
Chan() PairChan[K, V]
}
// Implementing the interface provides the way to
// convert the type to slice.
type Slicer[V any] interface {
Slice() []V
}
// Implementing the interface provides us the way to
// convert the type to map.
type Mapper[K comparable, V any] interface {
Map() map[K] V
}

27
src/iterx/pair.go Normal file
View file

@ -0,0 +1,27 @@
package iterx
// The type describes pair of key and value.
type Pair[K any, V any] struct {
V V
K K
}
// The type describes channel of pairs.
type PairChan[K any, V any] chan Pair[K, V]
// Slice of pairs.
type Pairs[K any, V any] []Pair[K, V]
// ForEach for channels, like in JS.
// Be careful since the function does not close the
// channel so if fn breaks the loop then there can
// be values left.
func (pc PairChan[K, V]) ForEach(fn func(k K, v V) bool) {
for p := range pc {
if !fn(p.K, p.V) {
break
}
}
}

View file

@ -1,39 +1,7 @@
package mapx
// The type implements map type where
// you can get, set and delete by value
// since it store everything as ONLY entity
// both for keys and values way.
// Use only when you do not care about the order.
type UniqMap[K, V comparable] struct {
store map[K] V
rstore map[V] K
}
// Returns new empty UniqMap.
func NewUniq[K, V comparable]() *UniqMap[K, V] {
return &UniqMap[K, V]{
make(map[K] V),
make(map[V] K),
}
}
// Sets new value v for the k key.
func (m *UniqMap[K, V]) Set(k K, v V) {
m.store[k] = v
m.rstore[v] = k
}
// Get value by the k key.
func (m *UniqMap[K, V]) Get(k K) (V, bool) {
v, ok := m.store[k]
return v, ok
}
func (m *UniqMap[K, V]) GetByValue(v V) (K, bool) {
k, ok := m.rstore[v]
return k, ok
}
// The package implements some more specific
// map structures for special uses.
func Keys[K comparable, V any](m map[K] V) []K {
r := make([]K, 0, len(m))

36
src/mapx/ordered.go Normal file
View file

@ -0,0 +1,36 @@
package mapx
// The type makes the underlying map ordered,
// so every time you pass through all the values
// they will be in the same order.
type OrderedMap[K comparable, V any] struct {
store map[K] V
keys []K
}
// Returns the new empty ordered map.
func NewOrdered[K comparable, V any]() *OrderedMap[K, V] {
return &OrderedMap[K, V]{
store: make(map[K] V),
}
}
// Set or reset the value in the map.
func (m *OrderedMap[K, V]) Set(k K, v V) {
_, ok := m.store[k]
if !ok {
keys = append(keys, k)
}
m.store[k] = v
}
// Get the value from the map.
func (m *OrderedMap[K, V]) Get(k K) (V, bool) {
v, ok := m.store[k]
return v, ok
}
// Return channel of pairs.
func (m *OrderedMap[K, V]) Range() chan Pair

37
src/mapx/uniq.go Normal file
View file

@ -0,0 +1,37 @@
package mapx
// The type implements map type where
// you can get, set and delete by value
// since it store everything as ONLY entity
// both for keys and values way.
// Use only when you do not care about the order.
type UniqMap[K, V comparable] struct {
store map[K] V
rstore map[V] K
}
// Returns new empty UniqMap.
func NewUniq[K, V comparable]() *UniqMap[K, V] {
return &UniqMap[K, V]{
make(map[K] V),
make(map[V] K),
}
}
// Sets new value v for the k key.
func (m *UniqMap[K, V]) Set(k K, v V) {
m.store[k] = v
m.rstore[v] = k
}
// Get value by the k key.
func (m *UniqMap[K, V]) Get(k K) (V, bool) {
v, ok := m.store[k]
return v, ok
}
func (m *UniqMap[K, V]) GetByValue(v V) (K, bool) {
k, ok := m.rstore[v]
return k, ok
}

View file

@ -1,7 +1,7 @@
package poolx
import (
"github.com/surdeus/godat/src/llx"
"github.com/mojosa-software/godat/src/llx"
)
// Ordered value-only based structure.

55
src/rangex/range.go Normal file
View file

@ -0,0 +1,55 @@
package rangex
import (
"github.com/mojosa-software/godat/src/iterx"
cnts "golang.org/x/exp/constraints"
)
type Range[V cnts.Ordered] struct {
start, step, end V
}
// Returns the new Range strucucture with corresponding start, step and end.
// If the values can never reach the end then the function will return nil.
func New[V cnts.Ordered](start, step, end V) *Range[V] {
return &Range[V]{
start, step, end,
}
}
func (r *Range[V]) Chan() iterx.PairChan[int, V] {
start, step, end := r.start, r.step, r.end
c := make(iterx.PairChan[int, V])
go func(){
var compare func(a, b V) bool
less := func(a, b V) bool {
return a < b
}
more := func(a, b V) bool {
return a > b
}
if start < end {
compare = less
} else {
compare = more
}
j := 0
for i := start ; compare(i, end) ; i += step {
c <- iterx.Pair[int, V]{
K:j,
V:i,
}
j++
}
close(c)
}()
return c
}