From 84c615ac58f2508c83afe75122c69822db80787e Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Fri, 24 Oct 2014 13:32:28 -0400 Subject: [PATCH] add Traverse to seq --- seq/seq.go | 24 ++++++++++++++++++++++++ seq/seq_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/seq/seq.go b/seq/seq.go index 114c0a9..cb1d8fc 100644 --- a/seq/seq.go +++ b/seq/seq.go @@ -286,3 +286,27 @@ func DropWhile(pred func(types.Elem) bool, s Seq) Seq { } return s } + +// Runs pred on each element in the sequence, descending recursively if it +// encounters another Seq (without calling pred on that Seq). This amounts to a +// depth-first traverse. If pred ever returns false the traverse will stop. +// Returns false if the Traverse was stopped by pred, true otherwise. +func Traverse(pred func(types.Elem) bool, s Seq) bool { + var el types.Elem + var ok bool + for { + el, s, ok = s.FirstRest() + if !ok { + return true + } + var predRet bool + if inners, ok := el.(Seq); ok { + predRet = Traverse(pred, inners) + } else { + predRet = pred(el) + } + if !predRet { + return false + } + } +} diff --git a/seq/seq_test.go b/seq/seq_test.go index 406a59f..f053fb7 100644 --- a/seq/seq_test.go +++ b/seq/seq_test.go @@ -379,3 +379,49 @@ func TestDropWhile(t *T) { assertEmpty(l, t) assertEmpty(nl, t) } + +// Test Traversing a Seq until a given condition +func TestTraverse(t *T) { + var acc int + pred := func(el types.Elem) bool { + acc += el.(types.GoType).V.(int) + return true + } + + l := NewList() + acc = 0 + Traverse(pred, l) + assertValue(acc, 0, t) + + l2 := NewList(elemSliceV(0, 1, 2, 3)...) + acc = 0 + Traverse(pred, l2) + assertValue(acc, 6, t) + + l3 := NewList( + types.GoType{1}, + types.GoType{2}, + NewList(elemSliceV(4, 5, 6)...), + types.GoType{3}, + ) + acc = 0 + Traverse(pred, l3) + assertValue(acc, 21, t) + + pred = func(el types.Elem) bool { + i := el.(types.GoType).V.(int) + if i > 4 { + return false + } + acc += i + return true + } + + acc = 0 + Traverse(pred, l2) + assertValue(acc, 6, t) + + acc = 0 + Traverse(pred, l3) + assertValue(acc, 7, t) +}