mirror of
https://github.com/emirpasic/gods
synced 2024-11-18 09:25:50 +00:00
commit
9078485d8b
70
README.md
70
README.md
@ -649,8 +649,9 @@ All ordered containers have stateful iterators. Typically an iterator is obtaine
|
||||
|
||||
#### IteratorWithIndex
|
||||
|
||||
A [iterator](#iterator) whose elements are referenced by an index. Typical usage:
|
||||
An [iterator](#iterator) whose elements are referenced by an index.
|
||||
|
||||
Typical usage:
|
||||
```go
|
||||
it := list.Iterator()
|
||||
for it.Next() {
|
||||
@ -659,44 +660,89 @@ for it.Next() {
|
||||
}
|
||||
```
|
||||
|
||||
Other usages:
|
||||
```go
|
||||
if it.First() {
|
||||
firstIndex, firstValue := it.Index(), it.Value()
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
for it.Begin(); it.Next(); {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### IteratorWithKey
|
||||
|
||||
A [iterator](#iterator) whose elements are referenced by a key. Typical usage:
|
||||
An [iterator](#iterator) whose elements are referenced by a key.
|
||||
|
||||
Typical usage:
|
||||
```go
|
||||
it := map.Iterator()
|
||||
it := tree.Iterator()
|
||||
for it.Next() {
|
||||
key, value := it.Key(), it.Value()
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### ReverseIteratorWithIndex
|
||||
|
||||
A [iterator](#iterator) whose elements are referenced by an index. Typical usage:
|
||||
Other usages:
|
||||
```go
|
||||
if it.First() {
|
||||
firstKey, firstValue := it.Key(), it.Value()
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
for it.Begin(); it.Next(); {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### 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.
|
||||
|
||||
Typical usage of iteration in reverse:
|
||||
```go
|
||||
it := list.Iterator()
|
||||
for it.Next() { /* Move to end */ }
|
||||
for it.Prev() {
|
||||
for it.End(); it.Prev(); {
|
||||
index, value := it.Index(), it.Value()
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Other usages:
|
||||
```go
|
||||
if it.Last() {
|
||||
lastIndex, lastValue := it.Index(), it.Value()
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### ReverseIteratorWithKey
|
||||
|
||||
A [iterator](#iterator) whose elements are referenced by a key. Typical usage:
|
||||
An [iterator](#iterator) whose elements are referenced by a key. Provides all functions as [IteratorWithKey](#iteratorwithkey), but can also be used for reverse iteration.
|
||||
|
||||
Typical usage of iteration in reverse:
|
||||
```go
|
||||
it := map.Iterator()
|
||||
for it.Next() { /* Move to end */ }
|
||||
for it.Prev() {
|
||||
it := tree.Iterator()
|
||||
for it.End(); it.Prev(); {
|
||||
key, value := it.Key(), it.Value()
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Other usages:
|
||||
```go
|
||||
if it.Last() {
|
||||
lastKey, lastValue := it.Key(), it.Value()
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Enumerable
|
||||
|
||||
Enumerable functions for ordered containers that implement [EnumerableWithIndex](#enumerablewithindex) or [EnumerableWithKey](#enumerablewithkey) interfaces.
|
||||
|
@ -30,56 +30,102 @@ package containers
|
||||
type IteratorWithIndex interface {
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
Next() bool
|
||||
|
||||
// Value returns the current element's value.
|
||||
// Does not modify the state of the iterator.
|
||||
Value() interface{}
|
||||
|
||||
// Index returns the current element's index.
|
||||
// Does not modify the state of the iterator.
|
||||
Index() int
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
Begin()
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
First() bool
|
||||
}
|
||||
|
||||
// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
|
||||
type IteratorWithKey interface {
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
Next() bool
|
||||
|
||||
// Value returns the current element's value.
|
||||
// Does not modify the state of the iterator.
|
||||
Value() interface{}
|
||||
|
||||
// Key returns the current element's key.
|
||||
// Does not modify the state of the iterator.
|
||||
Key() interface{}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
Begin()
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
First() bool
|
||||
}
|
||||
|
||||
// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
|
||||
//
|
||||
// Essentially it is the same as IteratorWithIndex, but provides additional Prev() function to enable traversal in reverse.
|
||||
// Essentially it is the same as IteratorWithIndex, but provides additional:
|
||||
//
|
||||
// Prev() function to enable traversal in reverse
|
||||
//
|
||||
// Last() function to move the iterator to the last element.
|
||||
//
|
||||
// End() function to move the iterator past the last element (one-past-the-end).
|
||||
type ReverseIteratorWithIndex interface {
|
||||
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
|
||||
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
Prev() bool
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
End()
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
Last() bool
|
||||
|
||||
IteratorWithIndex
|
||||
// Next() bool
|
||||
// Value() interface{}
|
||||
// Index() int
|
||||
}
|
||||
|
||||
// ReverseIteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
|
||||
//
|
||||
// Essentially it is the same as IteratorWithKey, but provides additional Prev() function to enable traversal in reverse.
|
||||
// Essentially it is the same as IteratorWithKey, but provides additional:
|
||||
//
|
||||
// Prev() function to enable traversal in reverse
|
||||
//
|
||||
// Last() function to move the iterator to the last element.
|
||||
type ReverseIteratorWithKey interface {
|
||||
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
|
||||
// If Prev() returns true, then previous element's index and value can be retrieved by Key() and Value().
|
||||
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
Prev() bool
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
End()
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
Last() bool
|
||||
|
||||
IteratorWithKey
|
||||
// Next() bool
|
||||
// Value() interface{}
|
||||
// Key() interface{}
|
||||
}
|
||||
|
73
examples/iteratorwithindex.go
Normal file
73
examples/iteratorwithindex.go
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright (c) 2015, Emir Pasic
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package examples
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emirpasic/gods/sets/treeset"
|
||||
)
|
||||
|
||||
// IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex
|
||||
func IteratorWithIndexExample() {
|
||||
set := treeset.NewWithStringComparator()
|
||||
set.Add("a", "b", "c")
|
||||
it := set.Iterator()
|
||||
|
||||
fmt.Print("\nForward iteration\n")
|
||||
for it.Next() {
|
||||
index, value := it.Index(), it.Value()
|
||||
fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c]
|
||||
}
|
||||
|
||||
fmt.Print("\nForward iteration (again)\n")
|
||||
for it.Begin(); it.Next(); {
|
||||
index, value := it.Index(), it.Value()
|
||||
fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c]
|
||||
}
|
||||
|
||||
fmt.Print("\nBackward iteration\n")
|
||||
for it.Prev() {
|
||||
index, value := it.Index(), it.Value()
|
||||
fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a]
|
||||
}
|
||||
|
||||
fmt.Print("\nBackward iteration (again)\n")
|
||||
for it.End(); it.Prev(); {
|
||||
index, value := it.Index(), it.Value()
|
||||
fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a]
|
||||
}
|
||||
|
||||
if it.First() {
|
||||
fmt.Print("\nFirst index: ", it.Index()) // First index: 0
|
||||
fmt.Print("\nFirst value: ", it.Value()) // First value: a
|
||||
}
|
||||
|
||||
if it.Last() {
|
||||
fmt.Print("\nLast index: ", it.Index()) // Last index: 3
|
||||
fmt.Print("\nLast value: ", it.Value()) // Last value: c
|
||||
}
|
||||
}
|
75
examples/iteratorwithkey.go
Normal file
75
examples/iteratorwithkey.go
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (c) 2015, Emir Pasic
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package examples
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emirpasic/gods/maps/treemap"
|
||||
)
|
||||
|
||||
// IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey
|
||||
func IteratorWithKeyExample() {
|
||||
m := treemap.NewWithIntComparator()
|
||||
m.Put(1, "a")
|
||||
m.Put(2, "b")
|
||||
m.Put(3, "a")
|
||||
it := m.Iterator()
|
||||
|
||||
fmt.Print("\nForward iteration\n")
|
||||
for it.Next() {
|
||||
key, value := it.Key(), it.Value()
|
||||
fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c]
|
||||
}
|
||||
|
||||
fmt.Print("\nForward iteration (again)\n")
|
||||
for it.Begin(); it.Next(); {
|
||||
key, value := it.Key(), it.Value()
|
||||
fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c]
|
||||
}
|
||||
|
||||
fmt.Print("\nBackward iteration\n")
|
||||
for it.Prev() {
|
||||
key, value := it.Key(), it.Value()
|
||||
fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a]
|
||||
}
|
||||
|
||||
fmt.Print("\nBackward iteration (again)\n")
|
||||
for it.End(); it.Prev(); {
|
||||
key, value := it.Key(), it.Value()
|
||||
fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a]
|
||||
}
|
||||
|
||||
if it.First() {
|
||||
fmt.Print("\nFirst key: ", it.Key()) // First key: 0
|
||||
fmt.Print("\nFirst value: ", it.Value()) // First value: a
|
||||
}
|
||||
|
||||
if it.Last() {
|
||||
fmt.Print("\nLast key: ", it.Key()) // Last key: 3
|
||||
fmt.Print("\nLast value: ", it.Value()) // Last value: c
|
||||
}
|
||||
}
|
@ -193,6 +193,7 @@ func (list *List) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.index < iterator.list.size {
|
||||
@ -223,6 +224,34 @@ func (iterator *Iterator) Index() int {
|
||||
return iterator.index
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.index = -1
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.index = iterator.list.size
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.Prev()
|
||||
}
|
||||
|
||||
// Each calls the given function once for each element, passing that element's index and value.
|
||||
func (list *List) Each(f func(index int, value interface{})) {
|
||||
iterator := list.Iterator()
|
||||
|
@ -379,6 +379,75 @@ func TestListIteratorPrev(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorBegin(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
it.Begin()
|
||||
list.Add("a", "b", "c")
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorEnd(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
|
||||
if index := it.Index(); index != -1 {
|
||||
t.Errorf("Got %v expected %v", index, -1)
|
||||
}
|
||||
|
||||
it.End()
|
||||
if index := it.Index(); index != 0 {
|
||||
t.Errorf("Got %v expected %v", index, 0)
|
||||
}
|
||||
|
||||
list.Add("a", "b", "c")
|
||||
it.End()
|
||||
if index := it.Index(); index != list.Size() {
|
||||
t.Errorf("Got %v expected %v", index, list.Size())
|
||||
}
|
||||
|
||||
it.Prev()
|
||||
if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorFirst(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
list.Add("a", "b", "c")
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorLast(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
list.Add("a", "b", "c")
|
||||
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 2 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkList(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
list := New()
|
||||
|
@ -314,6 +314,7 @@ func (list *List) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.index < iterator.list.size {
|
||||
@ -362,6 +363,36 @@ func (iterator *Iterator) Index() int {
|
||||
return iterator.index
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.index = -1
|
||||
iterator.element = nil
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.index = iterator.list.size
|
||||
iterator.element = iterator.list.last
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.Prev()
|
||||
}
|
||||
|
||||
// Each calls the given function once for each element, passing that element's index and value.
|
||||
func (list *List) Each(f func(index int, value interface{})) {
|
||||
iterator := list.Iterator()
|
||||
|
@ -379,6 +379,75 @@ func TestListIteratorPrev(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorBegin(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
it.Begin()
|
||||
list.Add("a", "b", "c")
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorEnd(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
|
||||
if index := it.Index(); index != -1 {
|
||||
t.Errorf("Got %v expected %v", index, -1)
|
||||
}
|
||||
|
||||
it.End()
|
||||
if index := it.Index(); index != 0 {
|
||||
t.Errorf("Got %v expected %v", index, 0)
|
||||
}
|
||||
|
||||
list.Add("a", "b", "c")
|
||||
it.End()
|
||||
if index := it.Index(); index != list.Size() {
|
||||
t.Errorf("Got %v expected %v", index, list.Size())
|
||||
}
|
||||
|
||||
it.Prev()
|
||||
if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorFirst(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
list.Add("a", "b", "c")
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorLast(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
list.Add("a", "b", "c")
|
||||
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 2 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkList(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
list := New()
|
||||
|
@ -286,6 +286,7 @@ func (list *List) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.index < iterator.list.size {
|
||||
@ -315,6 +316,21 @@ func (iterator *Iterator) Index() int {
|
||||
return iterator.index
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.index = -1
|
||||
iterator.element = nil
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Each calls the given function once for each element, passing that element's index and value.
|
||||
func (list *List) Each(f func(index int, value interface{})) {
|
||||
iterator := list.Iterator()
|
||||
|
@ -338,6 +338,35 @@ func TestListIteratorNext(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorBegin(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
it.Begin()
|
||||
list.Add("a", "b", "c")
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorFirst(t *testing.T) {
|
||||
list := New()
|
||||
it := list.Iterator()
|
||||
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
list.Add("a", "b", "c")
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkList(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
list := New()
|
||||
|
@ -140,13 +140,14 @@ func (m *Map) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
return iterator.iterator.Next()
|
||||
}
|
||||
|
||||
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
|
||||
// If Prev() returns true, then previous element's index and value can be retrieved by Key() and Value().
|
||||
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Prev() bool {
|
||||
return iterator.iterator.Prev()
|
||||
@ -164,6 +165,32 @@ func (iterator *Iterator) Key() interface{} {
|
||||
return iterator.iterator.Key()
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.iterator.Begin()
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.iterator.End()
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator
|
||||
func (iterator *Iterator) First() bool {
|
||||
return iterator.iterator.First()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
return iterator.iterator.Last()
|
||||
}
|
||||
|
||||
// Each calls the given function once for each element, passing that element's key and value.
|
||||
func (m *Map) Each(f func(key interface{}, value interface{})) {
|
||||
iterator := m.Iterator()
|
||||
|
@ -377,7 +377,6 @@ func TestMapIteratorPrev(t *testing.T) {
|
||||
}
|
||||
countDown := m.Size()
|
||||
for it.Prev() {
|
||||
countDown--
|
||||
key := it.Key()
|
||||
value := it.Value()
|
||||
switch key {
|
||||
@ -399,13 +398,70 @@ func TestMapIteratorPrev(t *testing.T) {
|
||||
if actualValue, expectedValue := value, countDown; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
countDown--
|
||||
}
|
||||
// one less that in Next(), thus "1"
|
||||
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
|
||||
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapIteratorBegin(t *testing.T) {
|
||||
m := NewWithIntComparator()
|
||||
it := m.Iterator()
|
||||
it.Begin()
|
||||
m.Put(3, "c")
|
||||
m.Put(1, "a")
|
||||
m.Put(2, "b")
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapTreeIteratorEnd(t *testing.T) {
|
||||
m := NewWithIntComparator()
|
||||
it := m.Iterator()
|
||||
m.Put(3, "c")
|
||||
m.Put(1, "a")
|
||||
m.Put(2, "b")
|
||||
it.End()
|
||||
it.Prev()
|
||||
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapIteratorFirst(t *testing.T) {
|
||||
m := NewWithIntComparator()
|
||||
m.Put(3, "c")
|
||||
m.Put(1, "a")
|
||||
m.Put(2, "b")
|
||||
it := m.Iterator()
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapIteratorLast(t *testing.T) {
|
||||
m := NewWithIntComparator()
|
||||
m.Put(3, "c")
|
||||
m.Put(1, "a")
|
||||
m.Put(2, "b")
|
||||
it := m.Iterator()
|
||||
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMap(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
m := NewWithIntComparator()
|
||||
|
@ -120,6 +120,7 @@ func (set *Set) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.index < iterator.tree.Size() {
|
||||
@ -150,6 +151,36 @@ func (iterator *Iterator) Index() int {
|
||||
return iterator.index
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.index = -1
|
||||
iterator.iterator.Begin()
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.index = iterator.tree.Size()
|
||||
iterator.iterator.End()
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.iterator.Last()
|
||||
}
|
||||
|
||||
// Each calls the given function once for each element, passing that element's index and value.
|
||||
func (set *Set) Each(f func(index int, value interface{})) {
|
||||
iterator := set.Iterator()
|
||||
|
@ -278,6 +278,69 @@ func TestSetIteratorPrev(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetIteratorBegin(t *testing.T) {
|
||||
m := NewWithStringComparator()
|
||||
it := m.Iterator()
|
||||
it.Begin()
|
||||
m.Add("a", "b", "c")
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetIteratorEnd(t *testing.T) {
|
||||
set := NewWithStringComparator()
|
||||
it := set.Iterator()
|
||||
|
||||
if index := it.Index(); index != -1 {
|
||||
t.Errorf("Got %v expected %v", index, -1)
|
||||
}
|
||||
|
||||
it.End()
|
||||
if index := it.Index(); index != 0 {
|
||||
t.Errorf("Got %v expected %v", index, 0)
|
||||
}
|
||||
|
||||
set.Add("a", "b", "c")
|
||||
it.End()
|
||||
if index := it.Index(); index != set.Size() {
|
||||
t.Errorf("Got %v expected %v", index, set.Size())
|
||||
}
|
||||
|
||||
it.Prev()
|
||||
if index, value := it.Index(), it.Value(); index != set.Size()-1 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, set.Size()-1, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetIteratorFirst(t *testing.T) {
|
||||
set := NewWithStringComparator()
|
||||
set.Add("a", "b", "c")
|
||||
it := set.Iterator()
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetIteratorLast(t *testing.T) {
|
||||
set := NewWithStringComparator()
|
||||
set.Add("a", "b", "c")
|
||||
it := set.Iterator()
|
||||
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 3 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 3, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSet(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
set := NewWithIntComparator()
|
||||
|
@ -111,6 +111,7 @@ func (stack *Stack) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.index < iterator.stack.Size() {
|
||||
@ -142,6 +143,34 @@ func (iterator *Iterator) Index() int {
|
||||
return iterator.index
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.index = -1
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.index = iterator.stack.Size()
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.Prev()
|
||||
}
|
||||
|
||||
// String returns a string representation of container
|
||||
func (stack *Stack) String() string {
|
||||
str := "ArrayStack\n"
|
||||
|
@ -176,6 +176,83 @@ func TestStackIteratorPrev(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackIteratorBegin(t *testing.T) {
|
||||
stack := New()
|
||||
it := stack.Iterator()
|
||||
it.Begin()
|
||||
stack.Push("a")
|
||||
stack.Push("b")
|
||||
stack.Push("c")
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackIteratorEnd(t *testing.T) {
|
||||
stack := New()
|
||||
it := stack.Iterator()
|
||||
|
||||
if index := it.Index(); index != -1 {
|
||||
t.Errorf("Got %v expected %v", index, -1)
|
||||
}
|
||||
|
||||
it.End()
|
||||
if index := it.Index(); index != 0 {
|
||||
t.Errorf("Got %v expected %v", index, 0)
|
||||
}
|
||||
|
||||
stack.Push("a")
|
||||
stack.Push("b")
|
||||
stack.Push("c")
|
||||
it.End()
|
||||
if index := it.Index(); index != stack.Size() {
|
||||
t.Errorf("Got %v expected %v", index, stack.Size())
|
||||
}
|
||||
|
||||
it.Prev()
|
||||
if index, value := it.Index(), it.Value(); index != stack.Size()-1 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, stack.Size()-1, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackIteratorFirst(t *testing.T) {
|
||||
stack := New()
|
||||
it := stack.Iterator()
|
||||
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
stack.Push("a")
|
||||
stack.Push("b")
|
||||
stack.Push("c")
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackIteratorLast(t *testing.T) {
|
||||
stack := New()
|
||||
it := stack.Iterator()
|
||||
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
stack.Push("a")
|
||||
stack.Push("b")
|
||||
stack.Push("c")
|
||||
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 2 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStack(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
stack := New()
|
||||
|
@ -106,6 +106,7 @@ func (stack *Stack) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.index < iterator.stack.Size() {
|
||||
@ -127,6 +128,20 @@ func (iterator *Iterator) Index() int {
|
||||
return iterator.index
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.index = -1
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// String returns a string representation of container
|
||||
func (stack *Stack) String() string {
|
||||
str := "LinkedListStack\n"
|
||||
|
@ -136,6 +136,39 @@ func TestStackIterator(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackIteratorBegin(t *testing.T) {
|
||||
stack := New()
|
||||
it := stack.Iterator()
|
||||
it.Begin()
|
||||
stack.Push("a")
|
||||
stack.Push("b")
|
||||
stack.Push("c")
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackIteratorFirst(t *testing.T) {
|
||||
stack := New()
|
||||
it := stack.Iterator()
|
||||
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
stack.Push("a")
|
||||
stack.Push("b")
|
||||
stack.Push("c")
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStack(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
stack := New()
|
||||
|
@ -127,6 +127,7 @@ func (heap *Heap) Iterator() Iterator {
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.index < iterator.heap.Size() {
|
||||
@ -158,6 +159,34 @@ func (iterator *Iterator) Index() int {
|
||||
return iterator.index
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.index = -1
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.index = iterator.heap.Size()
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.Prev()
|
||||
}
|
||||
|
||||
// String returns a string representation of container
|
||||
func (heap *Heap) String() string {
|
||||
str := "BinaryHeap\n"
|
||||
|
@ -191,6 +191,83 @@ func TestBinaryHeapIteratorPrev(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBinaryHeapIteratorBegin(t *testing.T) {
|
||||
heap := NewWithIntComparator()
|
||||
it := heap.Iterator()
|
||||
it.Begin()
|
||||
heap.Push(2)
|
||||
heap.Push(3)
|
||||
heap.Push(1)
|
||||
for it.Next() {
|
||||
}
|
||||
it.Begin()
|
||||
it.Next()
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != 1 {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIteratorEnd(t *testing.T) {
|
||||
heap := NewWithIntComparator()
|
||||
it := heap.Iterator()
|
||||
|
||||
if index := it.Index(); index != -1 {
|
||||
t.Errorf("Got %v expected %v", index, -1)
|
||||
}
|
||||
|
||||
it.End()
|
||||
if index := it.Index(); index != 0 {
|
||||
t.Errorf("Got %v expected %v", index, 0)
|
||||
}
|
||||
|
||||
heap.Push(3) // [3]
|
||||
heap.Push(2) // [2,3]
|
||||
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
|
||||
it.End()
|
||||
if index := it.Index(); index != heap.Size() {
|
||||
t.Errorf("Got %v expected %v", index, heap.Size())
|
||||
}
|
||||
|
||||
it.Prev()
|
||||
if index, value := it.Index(), it.Value(); index != heap.Size()-1 || value != 2 {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, heap.Size()-1, 2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackIteratorFirst(t *testing.T) {
|
||||
heap := NewWithIntComparator()
|
||||
it := heap.Iterator()
|
||||
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
heap.Push(3) // [3]
|
||||
heap.Push(2) // [2,3]
|
||||
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 0 || value != 1 {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBinaryHeapIteratorLast(t *testing.T) {
|
||||
tree := NewWithIntComparator()
|
||||
it := tree.Iterator()
|
||||
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
tree.Push(2)
|
||||
tree.Push(3)
|
||||
tree.Push(1) // [1,3,2](2 swapped with 1, hence last)
|
||||
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if index, value := it.Index(), it.Value(); index != 2 || value != 2 {
|
||||
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, 2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBinaryHeap(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
heap := NewWithIntComparator()
|
||||
|
@ -282,66 +282,103 @@ func (tree *Tree) Clear() {
|
||||
type Iterator struct {
|
||||
tree *Tree
|
||||
node *Node
|
||||
position position
|
||||
}
|
||||
|
||||
type position byte
|
||||
|
||||
const (
|
||||
begin, between, end position = 0, 1, 2
|
||||
)
|
||||
|
||||
// Iterator returns a stateful iterator whose elements are key/value pairs.
|
||||
func (tree *Tree) Iterator() Iterator {
|
||||
return Iterator{tree: tree, node: nil}
|
||||
return Iterator{tree: tree, node: nil, position: begin}
|
||||
}
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.node == nil {
|
||||
iterator.node = iterator.tree.Left()
|
||||
return iterator.node != nil
|
||||
if iterator.position == end {
|
||||
goto end
|
||||
}
|
||||
if iterator.position == begin {
|
||||
left := iterator.tree.Left()
|
||||
if left == nil {
|
||||
goto end
|
||||
}
|
||||
iterator.node = left
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Right != nil {
|
||||
iterator.node = iterator.node.Right
|
||||
for iterator.node.Left != nil {
|
||||
iterator.node = iterator.node.Left
|
||||
}
|
||||
return true
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Parent != nil {
|
||||
node := iterator.node
|
||||
for iterator.node.Parent != nil {
|
||||
iterator.node = iterator.node.Parent
|
||||
if iterator.tree.Comparator(node.Key, iterator.node.Key) <= 0 {
|
||||
return true
|
||||
goto between
|
||||
}
|
||||
}
|
||||
iterator.node = node // fix: if parent didn't satisfy the comparator criteria
|
||||
}
|
||||
|
||||
end:
|
||||
iterator.node = nil
|
||||
iterator.position = end
|
||||
return false
|
||||
|
||||
between:
|
||||
iterator.position = between
|
||||
return true
|
||||
}
|
||||
|
||||
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
|
||||
// If Prev() returns true, then previous element's index and value can be retrieved by Key() and Value().
|
||||
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Prev() bool {
|
||||
if iterator.node == nil {
|
||||
return false
|
||||
if iterator.position == begin {
|
||||
goto begin
|
||||
}
|
||||
if iterator.position == end {
|
||||
right := iterator.tree.Right()
|
||||
if right == nil {
|
||||
goto begin
|
||||
}
|
||||
iterator.node = right
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Left != nil {
|
||||
iterator.node = iterator.node.Left
|
||||
for iterator.node.Right != nil {
|
||||
iterator.node = iterator.node.Right
|
||||
}
|
||||
return true
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Parent != nil {
|
||||
node := iterator.node
|
||||
for iterator.node.Parent != nil {
|
||||
iterator.node = iterator.node.Parent
|
||||
if iterator.tree.Comparator(node.Key, iterator.node.Key) >= 0 {
|
||||
return true
|
||||
goto between
|
||||
}
|
||||
}
|
||||
iterator.node = node // fix: if parent didn't satisfy the comparator criteria
|
||||
}
|
||||
|
||||
begin:
|
||||
iterator.node = nil
|
||||
iterator.position = begin
|
||||
return false
|
||||
|
||||
between:
|
||||
iterator.position = between
|
||||
return true
|
||||
}
|
||||
|
||||
// Value returns the current element's value.
|
||||
@ -356,6 +393,36 @@ func (iterator *Iterator) Key() interface{} {
|
||||
return iterator.node.Key
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.node = nil
|
||||
iterator.position = begin
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.node = nil
|
||||
iterator.position = end
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.Prev()
|
||||
}
|
||||
|
||||
// String returns a string representation of container
|
||||
func (tree *Tree) String() string {
|
||||
str := "RedBlackTree\n"
|
||||
|
@ -282,7 +282,6 @@ func TestRedBlackTreeIterator1Prev(t *testing.T) {
|
||||
}
|
||||
countDown := tree.size
|
||||
for it.Prev() {
|
||||
countDown--
|
||||
key := it.Key()
|
||||
switch key {
|
||||
case countDown:
|
||||
@ -294,9 +293,9 @@ func TestRedBlackTreeIterator1Prev(t *testing.T) {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
countDown--
|
||||
}
|
||||
// one less that in Next(), thus "1"
|
||||
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
|
||||
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
|
||||
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
@ -337,7 +336,6 @@ func TestRedBlackTreeIterator2Prev(t *testing.T) {
|
||||
}
|
||||
countDown := tree.size
|
||||
for it.Prev() {
|
||||
countDown--
|
||||
key := it.Key()
|
||||
switch key {
|
||||
case countDown:
|
||||
@ -349,9 +347,9 @@ func TestRedBlackTreeIterator2Prev(t *testing.T) {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
countDown--
|
||||
}
|
||||
// one less that in Next(), thus "1"
|
||||
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
|
||||
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
|
||||
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
@ -388,7 +386,6 @@ func TestRedBlackTreeIterator3Prev(t *testing.T) {
|
||||
}
|
||||
countDown := tree.size
|
||||
for it.Prev() {
|
||||
countDown--
|
||||
key := it.Key()
|
||||
switch key {
|
||||
case countDown:
|
||||
@ -400,9 +397,9 @@ func TestRedBlackTreeIterator3Prev(t *testing.T) {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
countDown--
|
||||
}
|
||||
// one less that in Next(), thus "1"
|
||||
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
|
||||
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
|
||||
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
@ -450,7 +447,7 @@ func TestRedBlackTreeIterator4Next(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedBlackTreeIterator4(t *testing.T) {
|
||||
func TestRedBlackTreeIterator4Prev(t *testing.T) {
|
||||
tree := NewWithIntComparator()
|
||||
tree.Put(13, 5)
|
||||
tree.Put(8, 3)
|
||||
@ -477,7 +474,6 @@ func TestRedBlackTreeIterator4(t *testing.T) {
|
||||
for it.Next() {
|
||||
}
|
||||
for it.Prev() {
|
||||
count--
|
||||
value := it.Value()
|
||||
switch value {
|
||||
case count:
|
||||
@ -489,13 +485,100 @@ func TestRedBlackTreeIterator4(t *testing.T) {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
count--
|
||||
}
|
||||
// one less that in Next(), thus "1"
|
||||
if actualValue, expectedValue := count, 1; actualValue != expectedValue {
|
||||
if actualValue, expectedValue := count, 0; actualValue != expectedValue {
|
||||
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedBlackTreeIteratorBegin(t *testing.T) {
|
||||
tree := NewWithIntComparator()
|
||||
tree.Put(3, "c")
|
||||
tree.Put(1, "a")
|
||||
tree.Put(2, "b")
|
||||
it := tree.Iterator()
|
||||
|
||||
if it.node != nil {
|
||||
t.Errorf("Got %v expected %v", it.node, nil)
|
||||
}
|
||||
|
||||
it.Begin()
|
||||
|
||||
if it.node != nil {
|
||||
t.Errorf("Got %v expected %v", it.node, nil)
|
||||
}
|
||||
|
||||
for it.Next() {
|
||||
}
|
||||
|
||||
it.Begin()
|
||||
|
||||
if it.node != nil {
|
||||
t.Errorf("Got %v expected %v", it.node, nil)
|
||||
}
|
||||
|
||||
it.Next()
|
||||
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedBlackTreeIteratorEnd(t *testing.T) {
|
||||
tree := NewWithIntComparator()
|
||||
it := tree.Iterator()
|
||||
|
||||
if it.node != nil {
|
||||
t.Errorf("Got %v expected %v", it.node, nil)
|
||||
}
|
||||
|
||||
it.End()
|
||||
if it.node != nil {
|
||||
t.Errorf("Got %v expected %v", it.node, nil)
|
||||
}
|
||||
|
||||
tree.Put(3, "c")
|
||||
tree.Put(1, "a")
|
||||
tree.Put(2, "b")
|
||||
it.End()
|
||||
if it.node != nil {
|
||||
t.Errorf("Got %v expected %v", it.node, nil)
|
||||
}
|
||||
|
||||
it.Prev()
|
||||
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedBlackTreeIteratorFirst(t *testing.T) {
|
||||
tree := NewWithIntComparator()
|
||||
tree.Put(3, "c")
|
||||
tree.Put(1, "a")
|
||||
tree.Put(2, "b")
|
||||
it := tree.Iterator()
|
||||
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedBlackTreeIteratorLast(t *testing.T) {
|
||||
tree := NewWithIntComparator()
|
||||
tree.Put(3, "c")
|
||||
tree.Put(1, "a")
|
||||
tree.Put(2, "b")
|
||||
it := tree.Iterator()
|
||||
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
|
||||
t.Errorf("Got %v expected %v", actualValue, expectedValue)
|
||||
}
|
||||
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
|
||||
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRedBlackTree(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
tree := NewWithIntComparator()
|
||||
|
Loading…
Reference in New Issue
Block a user