Recursive Iterators
Posted
by
soandos
on Stack Overflow
See other posts from Stack Overflow
or by soandos
Published on 2012-06-03T22:11:59Z
Indexed on
2012/06/03
22:40 UTC
Read the original article
Hit count: 209
I am having some trouble making an iterator that can traverse the following type of data structure.
I have a class called Expression
, which has one data member, a List<object>
.
This list can have any number of children, and some of those children might be other Expression objects.
I want to traverse this structure, and print out every non-list object (but I do want to print out the elements of the list of course), but before entering a list, I want to return "begin nest" and after I just exited a list, I want to return "end nest".
I was able to do this if I ignored the class wherever possible, and just had List<object>
objects with List<object>
items if I wanted a subExpression, but I would rather do away with this, and instead have an Expression
s as the sublists (it would make it easier to do operations on the object. I am aware that I could use extension methods on the List<object>
but it would not be appropriate (who wants an Evaluate
method on their list that takes no arguments?).
The code that I used to generate the origonal iterator (that works) is:
public IEnumerator GetEnumerator(){
return theIterator(expr).GetEnumerator();
}
private IEnumerable theIterator(object root) {
if ((root is List<object>)){
yield return " begin nest ";
foreach (var item in (List<object>)root){
foreach (var item2 in theIterator(item)){
yield return item2;
}
}
yield return " end nest ";
}
else
yield return root;
}
A type swap of List<object>
for expression did not work, and lead to a stackOverflow error. How should the iterator be implemented?
Update: Here is the swapped code:
public IEnumerator GetEnumerator() {
return this.GetEnumerator();
}
private IEnumerable theIterator(object root) {
if ((root is Expression)) {
yield return " begin nest ";
foreach (var item in (Expression)root) {
foreach (var item2 in theIterator(item))
yield return item2;
}
yield return " end nest ";
}
else
yield return root;
}
© Stack Overflow or respective owner