chore: update to use iterators on orderedmaps

This commit is contained in:
Tristan Cartledge
2024-08-14 12:10:07 +01:00
committed by quobix
parent c3eb16d4e4
commit 161a41f73b
73 changed files with 690 additions and 550 deletions

View File

@@ -7,6 +7,7 @@ package orderedmap
import (
"context"
"fmt"
"iter"
"reflect"
"slices"
"strings"
@@ -74,6 +75,102 @@ func (o *Map[K, V]) First() Pair[K, V] {
}
}
// FromOldest returns an iterator that yields the oldest key-value pair in the map.
func (o *Map[K, V]) FromOldest() iter.Seq2[K, V] {
return func(yield func(K, V) bool) {
if o == nil {
return
}
for k, v := range o.OrderedMap.FromOldest() {
if !yield(k, v) {
return
}
}
}
}
// FromNewest returns an iterator that yields the newest key-value pair in the map.
func (o *Map[K, V]) FromNewest() iter.Seq2[K, V] {
o.OrderedMap.FromNewest()
return func(yield func(K, V) bool) {
if o == nil {
return
}
for k, v := range o.OrderedMap.FromNewest() {
if !yield(k, v) {
return
}
}
}
}
// FromNewest returns an iterator that yields the newest key-value pair in the map.
func (o *Map[K, V]) KeysFromOldest() iter.Seq[K] {
return func(yield func(K) bool) {
if o == nil {
return
}
for k := range o.OrderedMap.KeysFromOldest() {
if !yield(k) {
return
}
}
}
}
// KeysFromNewest returns an iterator that yields the newest key in the map.
func (o *Map[K, V]) KeysFromNewest() iter.Seq[K] {
return func(yield func(K) bool) {
if o == nil {
return
}
for k := range o.OrderedMap.KeysFromNewest() {
if !yield(k) {
return
}
}
}
}
// ValuesFromOldest returns an iterator that yields the oldest value in the map.
func (o *Map[K, V]) ValuesFromOldest() iter.Seq[V] {
return func(yield func(V) bool) {
if o == nil {
return
}
for v := range o.OrderedMap.ValuesFromOldest() {
if !yield(v) {
return
}
}
}
}
// ValuesFromNewest returns an iterator that yields the newest value in the map.
func (o *Map[K, V]) ValuesFromNewest() iter.Seq[V] {
return func(yield func(V) bool) {
if o == nil {
return
}
for v := range o.OrderedMap.ValuesFromNewest() {
if !yield(v) {
return
}
}
}
}
// From creates a new ordered map from an iterator.
func From[K comparable, V any](iter iter.Seq2[K, V]) *Map[K, V] {
return &Map[K, V]{
OrderedMap: wk8orderedmap.From(iter),
}
}
// NewPair instantiates a `Pair` object for use with `FromPairs()`.
func NewPair[K comparable, V any](key K, value V) Pair[K, V] {
return &wrapPair[K, V]{

View File

@@ -364,6 +364,120 @@ func TestFromPairs(t *testing.T) {
})
}
func TestIterators(t *testing.T) {
om := orderedmap.New[int, any]()
om.Set(1, "bar")
om.Set(2, 28)
om.Set(3, 100)
om.Set(4, "baz")
om.Set(5, "28")
om.Set(6, "100")
om.Set(7, "baz")
om.Set(8, "baz")
expectedKeys := []int{1, 2, 3, 4, 5, 6, 7, 8}
expectedKeysFromNewest := []int{8, 7, 6, 5, 4, 3, 2, 1}
expectedValues := []any{"bar", 28, 100, "baz", "28", "100", "baz", "baz"}
expectedValuesFromNewest := []any{"baz", "baz", "100", "28", "baz", 100, 28, "bar"}
var keys []int
var values []any
for k, v := range om.FromOldest() {
keys = append(keys, k)
values = append(values, v)
}
assert.Equal(t, expectedKeys, keys)
assert.Equal(t, expectedValues, values)
keys, values = []int{}, []any{}
for k, v := range om.FromNewest() {
keys = append(keys, k)
values = append(values, v)
}
assert.Equal(t, expectedKeysFromNewest, keys)
assert.Equal(t, expectedValuesFromNewest, values)
keys = []int{}
for k := range om.KeysFromOldest() {
keys = append(keys, k)
}
assert.Equal(t, expectedKeys, keys)
keys = []int{}
for k := range om.KeysFromNewest() {
keys = append(keys, k)
}
assert.Equal(t, expectedKeysFromNewest, keys)
values = []any{}
for v := range om.ValuesFromOldest() {
values = append(values, v)
}
assert.Equal(t, expectedValues, values)
values = []any{}
for v := range om.ValuesFromNewest() {
values = append(values, v)
}
assert.Equal(t, expectedValuesFromNewest, values)
}
func TestIteratorsFrom(t *testing.T) {
om := orderedmap.New[int, any]()
om.Set(1, "bar")
om.Set(2, 28)
om.Set(3, 100)
om.Set(4, "baz")
om.Set(5, "28")
om.Set(6, "100")
om.Set(7, "baz")
om.Set(8, "baz")
om2 := orderedmap.From(om.FromOldest())
expectedKeys := []int{1, 2, 3, 4, 5, 6, 7, 8}
expectedValues := []any{"bar", 28, 100, "baz", "28", "100", "baz", "baz"}
var keys []int
var values []any
for k, v := range om2.FromOldest() {
keys = append(keys, k)
values = append(values, v)
}
assert.Equal(t, expectedKeys, keys)
assert.Equal(t, expectedValues, values)
expectedKeysFromNewest := []int{8, 7, 6, 5, 4, 3, 2, 1}
expectedValuesFromNewest := []any{"baz", "baz", "100", "28", "baz", 100, 28, "bar"}
om2 = orderedmap.From(om.FromNewest())
keys = []int{}
values = []any{}
for k, v := range om2.FromOldest() {
keys = append(keys, k)
values = append(values, v)
}
assert.Equal(t, expectedKeysFromNewest, keys)
assert.Equal(t, expectedValuesFromNewest, values)
}
func requireClosed[K comparable, V any](t *testing.T, c <-chan orderedmap.Pair[K, V]) {
select {
case pair := <-c: