diff --git a/stacks/arraystack/arraystack.go b/stacks/arraystack/arraystack.go index 407cdf0..4b670dd 100644 --- a/stacks/arraystack/arraystack.go +++ b/stacks/arraystack/arraystack.go @@ -32,6 +32,7 @@ package arraystack import ( "fmt" + "github.com/emirpasic/gods/containers" "github.com/emirpasic/gods/lists/arraylist" "github.com/emirpasic/gods/stacks" "strings" @@ -39,6 +40,7 @@ import ( func assertInterfaceImplementation() { var _ stacks.Stack = (*Stack)(nil) + var _ containers.Iterator = (*Iterator)(nil) } type Stack struct { @@ -94,6 +96,29 @@ func (stack *Stack) Values() []interface{} { return elements } +type Iterator struct { + stack *Stack + index int +} + +func (stack *Stack) Iterator() Iterator { + return Iterator{stack: stack, index: -1} +} + +func (iterator *Iterator) Next() bool { + iterator.index += 1 + return iterator.stack.withinRange(iterator.index) +} + +func (iterator *Iterator) Value() interface{} { + value, _ := iterator.stack.list.Get(iterator.stack.list.Size() - iterator.index - 1) // in reverse (LIFO) + return value +} + +func (iterator *Iterator) Index() interface{} { + return iterator.index +} + func (stack *Stack) String() string { str := "ArrayStack\n" values := []string{} @@ -103,3 +128,8 @@ func (stack *Stack) String() string { str += strings.Join(values, ", ") return str } + +// Check that the index is withing bounds of the list +func (stack *Stack) withinRange(index int) bool { + return index >= 0 && index < stack.list.Size() +} diff --git a/stacks/arraystack/arraystack_test.go b/stacks/arraystack/arraystack_test.go index 62836db..65fed89 100644 --- a/stacks/arraystack/arraystack_test.go +++ b/stacks/arraystack/arraystack_test.go @@ -84,7 +84,41 @@ func TestArrayStack(t *testing.T) { if actualValue := stack.Values(); len(actualValue) != 0 { t.Errorf("Got %v expected %v", actualValue, "[]") } +} +func TestArrayStackIterator(t *testing.T) { + stack := New() + stack.Push("a") + stack.Push("b") + stack.Push("c") + + // Iterator + it := stack.Iterator() + for it.Next() { + index := it.Index() + value := it.Value() + switch index { + case 0: + if actualValue, expectedValue := value, "c"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + case 1: + if actualValue, expectedValue := value, "b"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + case 2: + if actualValue, expectedValue := value, "a"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + default: + t.Errorf("Too many") + } + } + stack.Clear() + it = stack.Iterator() + for it.Next() { + t.Errorf("Shouldn't iterate on empty stack") + } } func BenchmarkArrayStack(b *testing.B) {