mirror of
https://github.com/emirpasic/gods
synced 2024-11-13 19:12:07 +00:00
Implement NextTo and PrevTo for all iterators and containers (index or key, forward-only or reversable)
This commit is contained in:
parent
4209f34363
commit
08ae493e8a
76
README.md
76
README.md
@ -983,6 +983,22 @@ for it.Begin(); it.Next(); {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Seeking to a specific element:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Seek function, i.e. find element starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek to the condition and continue traversal from that point (forward).
|
||||||
|
// assumes it.Begin() was called.
|
||||||
|
for found := it.NextTo(seek); found; found = it.Next() {
|
||||||
|
index, value := it.Index(), it.Value()
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### IteratorWithKey
|
#### IteratorWithKey
|
||||||
|
|
||||||
An [iterator](#iterator) whose elements are referenced by a key.
|
An [iterator](#iterator) whose elements are referenced by a key.
|
||||||
@ -1010,6 +1026,22 @@ for it.Begin(); it.Next(); {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Seeking to a specific element from the current iterator position:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Seek function, i.e. find element starting with "b"
|
||||||
|
seek := func(key interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek to the condition and continue traversal from that point (forward).
|
||||||
|
// assumes it.Begin() was called.
|
||||||
|
for found := it.NextTo(seek); found; found = it.Next() {
|
||||||
|
key, value := it.Key(), it.Value()
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### ReverseIteratorWithIndex
|
#### ReverseIteratorWithIndex
|
||||||
|
|
||||||
An [iterator](#iterator) whose elements are referenced by an index. Provides all functions as [IteratorWithIndex](#iteratorwithindex), but can also be used for reverse iteration.
|
An [iterator](#iterator) whose elements are referenced by an index. Provides all functions as [IteratorWithIndex](#iteratorwithindex), but can also be used for reverse iteration.
|
||||||
@ -1031,6 +1063,22 @@ if it.Last() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Seeking to a specific element:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Seek function, i.e. find element starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek to the condition and continue traversal from that point (in reverse).
|
||||||
|
// assumes it.End() was called.
|
||||||
|
for found := it.PrevTo(seek); found; found = it.Prev() {
|
||||||
|
index, value := it.Index(), it.Value()
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### ReverseIteratorWithKey
|
#### ReverseIteratorWithKey
|
||||||
|
|
||||||
An [iterator](#iterator) whose elements are referenced by a key. Provides all functions as [IteratorWithKey](#iteratorwithkey), but can also be used for reverse iteration.
|
An [iterator](#iterator) whose elements are referenced by a key. Provides all functions as [IteratorWithKey](#iteratorwithkey), but can also be used for reverse iteration.
|
||||||
@ -1052,6 +1100,20 @@ if it.Last() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Seek function, i.e. find element starting with "b"
|
||||||
|
seek := func(key interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek to the condition and continue traversal from that point (in reverse).
|
||||||
|
// assumes it.End() was called.
|
||||||
|
for found := it.PrevTo(seek); found; found = it.Prev() {
|
||||||
|
key, value := it.Key(), it.Value()
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Enumerable
|
### Enumerable
|
||||||
|
|
||||||
Enumerable functions for ordered containers that implement [EnumerableWithIndex](#enumerablewithindex) or [EnumerableWithKey](#enumerablewithkey) interfaces.
|
Enumerable functions for ordered containers that implement [EnumerableWithIndex](#enumerablewithindex) or [EnumerableWithKey](#enumerablewithkey) interfaces.
|
||||||
@ -1489,13 +1551,19 @@ Coding style:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Install tooling and set path:
|
# Install tooling and set path:
|
||||||
go get github.com/golang/lint/golint
|
go install gotest.tools/gotestsum@latest
|
||||||
go get github.com/fzipp/gocyclo
|
go install golang.org/x/lint/golint@latest
|
||||||
go get github.com/kisielk/errcheck
|
go install github.com/kisielk/errcheck@latest
|
||||||
export PATH=$PATH:$GOPATH/bin
|
export PATH=$PATH:$GOPATH/bin
|
||||||
|
|
||||||
# Fix errors and warnings:
|
# Fix errors and warnings:
|
||||||
go fmt ./... && gofmt -s -w . && go vet ./... && go get ./... && go test ./... && golint ./... && gocyclo -avg -over 15 . && errcheck ./...
|
go fmt ./... &&
|
||||||
|
go test -v ./... &&
|
||||||
|
golint -set_exit_status ./... &&
|
||||||
|
! go fmt ./... 2>&1 | read &&
|
||||||
|
go vet -v ./... &&
|
||||||
|
gocyclo -avg -over 15 ../gods &&
|
||||||
|
errcheck ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
@ -28,6 +28,12 @@ type IteratorWithIndex interface {
|
|||||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||||
// Modifies the state of the iterator.
|
// Modifies the state of the iterator.
|
||||||
First() bool
|
First() bool
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
NextTo(func(index int, value interface{}) bool) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
|
// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
|
||||||
@ -54,6 +60,12 @@ type IteratorWithKey interface {
|
|||||||
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
|
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
|
||||||
// Modifies the state of the iterator.
|
// Modifies the state of the iterator.
|
||||||
First() bool
|
First() bool
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
NextTo(func(key interface{}, value interface{}) bool) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
|
// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
|
||||||
@ -80,6 +92,12 @@ type ReverseIteratorWithIndex interface {
|
|||||||
// Modifies the state of the iterator.
|
// Modifies the state of the iterator.
|
||||||
Last() bool
|
Last() bool
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
PrevTo(func(index int, value interface{}) bool) bool
|
||||||
|
|
||||||
IteratorWithIndex
|
IteratorWithIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,5 +123,11 @@ type ReverseIteratorWithKey interface {
|
|||||||
// Modifies the state of the iterator.
|
// Modifies the state of the iterator.
|
||||||
Last() bool
|
Last() bool
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
PrevTo(func(key interface{}, value interface{}) bool) bool
|
||||||
|
|
||||||
IteratorWithKey
|
IteratorWithKey
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/emirpasic/gods/sets/treeset"
|
"github.com/emirpasic/gods/sets/treeset"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex
|
// IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex
|
||||||
@ -48,4 +49,32 @@ func main() {
|
|||||||
fmt.Print("\nLast index: ", it.Index()) // Last index: 3
|
fmt.Print("\nLast index: ", it.Index()) // Last index: 3
|
||||||
fmt.Print("\nLast value: ", it.Value()) // Last value: c
|
fmt.Print("\nLast value: ", it.Value()) // Last value: c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seek element starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
it.Begin()
|
||||||
|
for found := it.NextTo(seek); found; found = it.Next() {
|
||||||
|
fmt.Print("\nNextTo index: ", it.Index())
|
||||||
|
fmt.Print("\nNextTo value: ", it.Value())
|
||||||
|
} /*
|
||||||
|
NextTo index: 1
|
||||||
|
NextTo value: "b"
|
||||||
|
NextTo index: 2
|
||||||
|
NextTo value: "c"
|
||||||
|
*/
|
||||||
|
|
||||||
|
it.End()
|
||||||
|
for found := it.PrevTo(seek); found; found = it.Prev() {
|
||||||
|
fmt.Print("\nNextTo index: ", it.Index())
|
||||||
|
fmt.Print("\nNextTo value: ", it.Value())
|
||||||
|
} /*
|
||||||
|
NextTo index: 1
|
||||||
|
NextTo value: "b"
|
||||||
|
NextTo index: 0
|
||||||
|
NextTo value: "a"
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,15 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/emirpasic/gods/maps/treemap"
|
"github.com/emirpasic/gods/maps/treemap"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey
|
// IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey
|
||||||
func main() {
|
func main() {
|
||||||
m := treemap.NewWithIntComparator()
|
m := treemap.NewWithIntComparator()
|
||||||
m.Put(1, "a")
|
m.Put(0, "a")
|
||||||
m.Put(2, "b")
|
m.Put(1, "b")
|
||||||
m.Put(3, "a")
|
m.Put(2, "c")
|
||||||
it := m.Iterator()
|
it := m.Iterator()
|
||||||
|
|
||||||
fmt.Print("\nForward iteration\n")
|
fmt.Print("\nForward iteration\n")
|
||||||
@ -47,7 +48,34 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if it.Last() {
|
if it.Last() {
|
||||||
fmt.Print("\nLast key: ", it.Key()) // Last key: 3
|
fmt.Print("\nLast key: ", it.Key()) // Last key: 2
|
||||||
fmt.Print("\nLast value: ", it.Value()) // Last value: c
|
fmt.Print("\nLast value: ", it.Value()) // Last value: c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seek key-value pair whose value starts with "b"
|
||||||
|
seek := func(key interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
it.Begin()
|
||||||
|
for found := it.NextTo(seek); found; found = it.Next() {
|
||||||
|
fmt.Print("\nNextTo key: ", it.Key())
|
||||||
|
fmt.Print("\nNextTo value: ", it.Value())
|
||||||
|
} /*
|
||||||
|
NextTo key: 1
|
||||||
|
NextTo value: "b"
|
||||||
|
NextTo key: 2
|
||||||
|
NextTo value: "c"
|
||||||
|
*/
|
||||||
|
|
||||||
|
it.End()
|
||||||
|
for found := it.PrevTo(seek); found; found = it.Prev() {
|
||||||
|
fmt.Print("\nNextTo key: ", it.Key())
|
||||||
|
fmt.Print("\nNextTo value: ", it.Value())
|
||||||
|
} /*
|
||||||
|
NextTo key: 1
|
||||||
|
NextTo value: "b"
|
||||||
|
NextTo key: 0
|
||||||
|
NextTo value: "a"
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ package arraylist
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -500,6 +501,106 @@ func TestListIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
it := list.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("xx", "yy")
|
||||||
|
it := list.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("aa", "bb", "cc")
|
||||||
|
it := list.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
it := list.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("xx", "yy")
|
||||||
|
it := list.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("aa", "bb", "cc")
|
||||||
|
it := list.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestListSerialization(t *testing.T) {
|
func TestListSerialization(t *testing.T) {
|
||||||
list := New()
|
list := New()
|
||||||
list.Add("a", "b", "c")
|
list.Add("a", "b", "c")
|
||||||
|
@ -81,3 +81,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package doublylinkedlist
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
@ -506,6 +507,106 @@ func TestListIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
it := list.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("xx", "yy")
|
||||||
|
it := list.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("aa", "bb", "cc")
|
||||||
|
it := list.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
it := list.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("xx", "yy")
|
||||||
|
it := list.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("aa", "bb", "cc")
|
||||||
|
it := list.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestListSerialization(t *testing.T) {
|
func TestListSerialization(t *testing.T) {
|
||||||
list := New()
|
list := New()
|
||||||
list.Add("a", "b", "c")
|
list.Add("a", "b", "c")
|
||||||
|
@ -102,3 +102,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -68,3 +68,17 @@ func (iterator *Iterator) First() bool {
|
|||||||
iterator.Begin()
|
iterator.Begin()
|
||||||
return iterator.Next()
|
return iterator.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package singlylinkedlist
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
@ -420,6 +421,55 @@ func TestListIteratorFirst(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
it := list.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("xx", "yy")
|
||||||
|
it := list.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
list := New()
|
||||||
|
list.Add("aa", "bb", "cc")
|
||||||
|
it := list.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestListSerialization(t *testing.T) {
|
func TestListSerialization(t *testing.T) {
|
||||||
list := New()
|
list := New()
|
||||||
list.Add("a", "b", "c")
|
list.Add("a", "b", "c")
|
||||||
|
@ -79,3 +79,31 @@ func (iterator *Iterator) First() bool {
|
|||||||
func (iterator *Iterator) Last() bool {
|
func (iterator *Iterator) Last() bool {
|
||||||
return iterator.iterator.Last()
|
return iterator.iterator.Last()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package linkedhashmap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -399,7 +400,7 @@ func TestMapIteratorBegin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMapTreeIteratorEnd(t *testing.T) {
|
func TestMapIteratorEnd(t *testing.T) {
|
||||||
m := New()
|
m := New()
|
||||||
it := m.Iterator()
|
it := m.Iterator()
|
||||||
m.Put(3, "c")
|
m.Put(3, "c")
|
||||||
@ -440,6 +441,112 @@ func TestMapIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMapIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
m := New()
|
||||||
|
it := m.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
m := New()
|
||||||
|
m.Put(0, "xx")
|
||||||
|
m.Put(1, "yy")
|
||||||
|
it := m.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
m := New()
|
||||||
|
m.Put(0, "aa")
|
||||||
|
m.Put(1, "bb")
|
||||||
|
m.Put(2, "cc")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMapIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
m := New()
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
m := New()
|
||||||
|
m.Put(0, "xx")
|
||||||
|
m.Put(1, "yy")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
m := New()
|
||||||
|
m.Put(0, "aa")
|
||||||
|
m.Put(1, "bb")
|
||||||
|
m.Put(2, "cc")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMapSerialization(t *testing.T) {
|
func TestMapSerialization(t *testing.T) {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
original := New()
|
original := New()
|
||||||
|
@ -75,3 +75,31 @@ func (iterator *Iterator) First() bool {
|
|||||||
func (iterator *Iterator) Last() bool {
|
func (iterator *Iterator) Last() bool {
|
||||||
return iterator.iterator.Last()
|
return iterator.iterator.Last()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ package treebidimap
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -432,7 +433,7 @@ func TestMapIteratorBegin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMapTreeIteratorEnd(t *testing.T) {
|
func TestMapIteratorEnd(t *testing.T) {
|
||||||
m := NewWith(utils.IntComparator, utils.StringComparator)
|
m := NewWith(utils.IntComparator, utils.StringComparator)
|
||||||
it := m.Iterator()
|
it := m.Iterator()
|
||||||
m.Put(3, "c")
|
m.Put(3, "c")
|
||||||
@ -473,6 +474,112 @@ func TestMapIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMapIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
m := NewWith(utils.IntComparator, utils.StringComparator)
|
||||||
|
it := m.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
m := NewWith(utils.IntComparator, utils.StringComparator)
|
||||||
|
m.Put(0, "xx")
|
||||||
|
m.Put(1, "yy")
|
||||||
|
it := m.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
m := NewWith(utils.IntComparator, utils.StringComparator)
|
||||||
|
m.Put(0, "aa")
|
||||||
|
m.Put(1, "bb")
|
||||||
|
m.Put(2, "cc")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMapIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
m := NewWith(utils.IntComparator, utils.StringComparator)
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
m := NewWith(utils.IntComparator, utils.StringComparator)
|
||||||
|
m.Put(0, "xx")
|
||||||
|
m.Put(1, "yy")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
m := NewWith(utils.IntComparator, utils.StringComparator)
|
||||||
|
m.Put(0, "aa")
|
||||||
|
m.Put(1, "bb")
|
||||||
|
m.Put(2, "cc")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMapSerialization(t *testing.T) {
|
func TestMapSerialization(t *testing.T) {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
original := NewWith(utils.StringComparator, utils.StringComparator)
|
original := NewWith(utils.StringComparator, utils.StringComparator)
|
||||||
|
@ -75,3 +75,31 @@ func (iterator *Iterator) First() bool {
|
|||||||
func (iterator *Iterator) Last() bool {
|
func (iterator *Iterator) Last() bool {
|
||||||
return iterator.iterator.Last()
|
return iterator.iterator.Last()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package treemap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -455,7 +456,7 @@ func TestMapIteratorBegin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMapTreeIteratorEnd(t *testing.T) {
|
func TestMapIteratorEnd(t *testing.T) {
|
||||||
m := NewWithIntComparator()
|
m := NewWithIntComparator()
|
||||||
it := m.Iterator()
|
it := m.Iterator()
|
||||||
m.Put(3, "c")
|
m.Put(3, "c")
|
||||||
@ -496,6 +497,112 @@ func TestMapIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMapIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
m := NewWithIntComparator()
|
||||||
|
it := m.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
m := NewWithIntComparator()
|
||||||
|
m.Put(0, "xx")
|
||||||
|
m.Put(1, "yy")
|
||||||
|
it := m.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
m := NewWithIntComparator()
|
||||||
|
m.Put(0, "aa")
|
||||||
|
m.Put(1, "bb")
|
||||||
|
m.Put(2, "cc")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMapIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
m := NewWithIntComparator()
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
m := NewWithIntComparator()
|
||||||
|
m.Put(0, "xx")
|
||||||
|
m.Put(1, "yy")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
m := NewWithIntComparator()
|
||||||
|
m.Put(0, "aa")
|
||||||
|
m.Put(1, "bb")
|
||||||
|
m.Put(2, "cc")
|
||||||
|
it := m.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty map")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMapSerialization(t *testing.T) {
|
func TestMapSerialization(t *testing.T) {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
original := NewWithStringComparator()
|
original := NewWithStringComparator()
|
||||||
|
@ -75,3 +75,31 @@ func (iterator *Iterator) First() bool {
|
|||||||
func (iterator *Iterator) Last() bool {
|
func (iterator *Iterator) Last() bool {
|
||||||
return iterator.iterator.Last()
|
return iterator.iterator.Last()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package linkedhashset
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -332,6 +333,106 @@ func TestSetIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
set := New()
|
||||||
|
it := set.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
set := New()
|
||||||
|
set.Add("xx", "yy")
|
||||||
|
it := set.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
set := New()
|
||||||
|
set.Add("aa", "bb", "cc")
|
||||||
|
it := set.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
set := New()
|
||||||
|
it := set.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
set := New()
|
||||||
|
set.Add("xx", "yy")
|
||||||
|
it := set.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
set := New()
|
||||||
|
set.Add("aa", "bb", "cc")
|
||||||
|
it := set.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetSerialization(t *testing.T) {
|
func TestSetSerialization(t *testing.T) {
|
||||||
set := New()
|
set := New()
|
||||||
set.Add("a", "b", "c")
|
set.Add("a", "b", "c")
|
||||||
|
@ -87,3 +87,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package treeset
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -341,6 +342,106 @@ func TestSetIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
set := NewWithStringComparator()
|
||||||
|
it := set.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
set := NewWithStringComparator()
|
||||||
|
set.Add("xx", "yy")
|
||||||
|
it := set.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
set := NewWithStringComparator()
|
||||||
|
set.Add("aa", "bb", "cc")
|
||||||
|
it := set.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
set := NewWithStringComparator()
|
||||||
|
it := set.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
set := NewWithStringComparator()
|
||||||
|
set.Add("xx", "yy")
|
||||||
|
it := set.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
set := NewWithStringComparator()
|
||||||
|
set.Add("aa", "bb", "cc")
|
||||||
|
it := set.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty set")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetSerialization(t *testing.T) {
|
func TestSetSerialization(t *testing.T) {
|
||||||
set := NewWithStringComparator()
|
set := NewWithStringComparator()
|
||||||
set.Add("a", "b", "c")
|
set.Add("a", "b", "c")
|
||||||
|
@ -6,6 +6,7 @@ package arraystack
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -232,6 +233,112 @@ func TestStackIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStackIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
it := stack.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
stack.Push("xx")
|
||||||
|
stack.Push("yy")
|
||||||
|
it := stack.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
stack.Push("aa")
|
||||||
|
stack.Push("bb")
|
||||||
|
stack.Push("cc")
|
||||||
|
it := stack.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "aa")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStackIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
it := stack.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
stack.Push("xx")
|
||||||
|
stack.Push("yy")
|
||||||
|
it := stack.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
stack.Push("aa")
|
||||||
|
stack.Push("bb")
|
||||||
|
stack.Push("cc")
|
||||||
|
it := stack.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 0 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "cc")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStackSerialization(t *testing.T) {
|
func TestStackSerialization(t *testing.T) {
|
||||||
stack := New()
|
stack := New()
|
||||||
stack.Push("a")
|
stack.Push("a")
|
||||||
|
@ -82,3 +82,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -58,3 +58,17 @@ func (iterator *Iterator) First() bool {
|
|||||||
iterator.Begin()
|
iterator.Begin()
|
||||||
return iterator.Next()
|
return iterator.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package linkedliststack
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -148,6 +149,58 @@ func TestStackIteratorFirst(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStackIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
it := stack.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
stack.Push("xx")
|
||||||
|
stack.Push("yy")
|
||||||
|
it := stack.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
stack := New()
|
||||||
|
stack.Push("aa")
|
||||||
|
stack.Push("bb")
|
||||||
|
stack.Push("cc")
|
||||||
|
it := stack.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty stack")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "aa")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStackSerialization(t *testing.T) {
|
func TestStackSerialization(t *testing.T) {
|
||||||
stack := New()
|
stack := New()
|
||||||
stack.Push("a")
|
stack.Push("a")
|
||||||
|
@ -5,6 +5,7 @@ package avltree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -556,6 +557,112 @@ func TestAVLTreeIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAVLTreeIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(0, "xx")
|
||||||
|
tree.Put(1, "yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(2, "cc")
|
||||||
|
tree.Put(0, "aa")
|
||||||
|
tree.Put(1, "bb")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAVLTreeIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(0, "xx")
|
||||||
|
tree.Put(1, "yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(2, "cc")
|
||||||
|
tree.Put(0, "aa")
|
||||||
|
tree.Put(1, "bb")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAVLTreeSerialization(t *testing.T) {
|
func TestAVLTreeSerialization(t *testing.T) {
|
||||||
tree := NewWithStringComparator()
|
tree := NewWithStringComparator()
|
||||||
tree.Put("c", "3")
|
tree.Put("c", "3")
|
||||||
|
@ -115,3 +115,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package binaryheap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ func TestBinaryHeapIteratorBegin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListIteratorEnd(t *testing.T) {
|
func TestBinaryHeapIteratorEnd(t *testing.T) {
|
||||||
heap := NewWithIntComparator()
|
heap := NewWithIntComparator()
|
||||||
it := heap.Iterator()
|
it := heap.Iterator()
|
||||||
|
|
||||||
@ -225,7 +226,7 @@ func TestListIteratorEnd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStackIteratorFirst(t *testing.T) {
|
func TestBinaryHeapIteratorFirst(t *testing.T) {
|
||||||
heap := NewWithIntComparator()
|
heap := NewWithIntComparator()
|
||||||
it := heap.Iterator()
|
it := heap.Iterator()
|
||||||
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
||||||
@ -259,6 +260,112 @@ func TestBinaryHeapIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBinaryHeapIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithStringComparator()
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithStringComparator()
|
||||||
|
tree.Push("xx")
|
||||||
|
tree.Push("yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithStringComparator()
|
||||||
|
tree.Push("aa")
|
||||||
|
tree.Push("bb")
|
||||||
|
tree.Push("cc")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBinaryHeapIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index int, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithStringComparator()
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithStringComparator()
|
||||||
|
tree.Push("xx")
|
||||||
|
tree.Push("yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithStringComparator()
|
||||||
|
tree.Push("aa")
|
||||||
|
tree.Push("bb")
|
||||||
|
tree.Push("cc")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty list")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Index(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBinaryHeapSerialization(t *testing.T) {
|
func TestBinaryHeapSerialization(t *testing.T) {
|
||||||
heap := NewWithStringComparator()
|
heap := NewWithStringComparator()
|
||||||
|
|
||||||
|
@ -82,3 +82,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(index int, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
index, value := iterator.Index(), iterator.Value()
|
||||||
|
if f(index, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package btree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1074,6 +1075,112 @@ func assertValidTreeNode(t *testing.T, node *Node, expectedEntries int, expected
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBTreeIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator(3)
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator(3)
|
||||||
|
tree.Put(0, "xx")
|
||||||
|
tree.Put(1, "yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator(3)
|
||||||
|
tree.Put(2, "cc")
|
||||||
|
tree.Put(0, "aa")
|
||||||
|
tree.Put(1, "bb")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBTreeIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator(3)
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator(3)
|
||||||
|
tree.Put(0, "xx")
|
||||||
|
tree.Put(1, "yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator(3)
|
||||||
|
tree.Put(2, "cc")
|
||||||
|
tree.Put(0, "aa")
|
||||||
|
tree.Put(1, "bb")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBTreeSerialization(t *testing.T) {
|
func TestBTreeSerialization(t *testing.T) {
|
||||||
tree := NewWithStringComparator(3)
|
tree := NewWithStringComparator(3)
|
||||||
tree.Put("c", "3")
|
tree.Put("c", "3")
|
||||||
|
@ -191,3 +191,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -159,3 +159,31 @@ func (iterator *Iterator) Last() bool {
|
|||||||
iterator.End()
|
iterator.End()
|
||||||
return iterator.Prev()
|
return iterator.Prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextTo moves the iterator to the next element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) NextTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Next() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the
|
||||||
|
// passed function, and returns true if there was a next element in the container.
|
||||||
|
// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||||
|
// Modifies the state of the iterator.
|
||||||
|
func (iterator *Iterator) PrevTo(f func(key interface{}, value interface{}) bool) bool {
|
||||||
|
for iterator.Prev() {
|
||||||
|
key, value := iterator.Key(), iterator.Value()
|
||||||
|
if f(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package redblacktree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -557,6 +558,112 @@ func TestRedBlackTreeIteratorLast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRedBlackTreeIteratorNextTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(0, "xx")
|
||||||
|
tree.Put(1, "yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
for it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(2, "cc")
|
||||||
|
tree.Put(0, "aa")
|
||||||
|
tree.Put(1, "bb")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.Begin()
|
||||||
|
if !it.NextTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Next() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 2 || value.(string) != "cc" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc")
|
||||||
|
}
|
||||||
|
if it.Next() {
|
||||||
|
t.Errorf("Should not go past last element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRedBlackTreeIteratorPrevTo(t *testing.T) {
|
||||||
|
// Sample seek function, i.e. string starting with "b"
|
||||||
|
seek := func(index interface{}, value interface{}) bool {
|
||||||
|
return strings.HasSuffix(value.(string), "b")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (empty)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (not found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(0, "xx")
|
||||||
|
tree.Put(1, "yy")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
for it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrevTo (found)
|
||||||
|
{
|
||||||
|
tree := NewWithIntComparator()
|
||||||
|
tree.Put(2, "cc")
|
||||||
|
tree.Put(0, "aa")
|
||||||
|
tree.Put(1, "bb")
|
||||||
|
it := tree.Iterator()
|
||||||
|
it.End()
|
||||||
|
if !it.PrevTo(seek) {
|
||||||
|
t.Errorf("Shouldn't iterate on empty tree")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 1 || value.(string) != "bb" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb")
|
||||||
|
}
|
||||||
|
if !it.Prev() {
|
||||||
|
t.Errorf("Should go to first element")
|
||||||
|
}
|
||||||
|
if index, value := it.Key(), it.Value(); index != 0 || value.(string) != "aa" {
|
||||||
|
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa")
|
||||||
|
}
|
||||||
|
if it.Prev() {
|
||||||
|
t.Errorf("Should not go before first element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRedBlackTreeSerialization(t *testing.T) {
|
func TestRedBlackTreeSerialization(t *testing.T) {
|
||||||
tree := NewWithStringComparator()
|
tree := NewWithStringComparator()
|
||||||
tree.Put("c", "3")
|
tree.Put("c", "3")
|
||||||
|
Loading…
Reference in New Issue
Block a user