Wiki

root/cobra/trunk/HowTo/310-IterateThroughRecursiveDataWithYield.cobra

Revision 2335, 2.3 KB (checked in by Chuck.Esterbrook, 2 years ago)

Improvements to the How-To's.

  • Property svn:eol-style set to native
Line 
1"""
2Iterate Through Recursive Data With Yield
3
4If you study the _scanInOrder method below you will see that implementing it with `yield` is very
5straightforward. Without `yield` the alternative is to write a helper class that implements
6IEnumerator<of T> and maintains state variables to track its current position in between calls to
7.moveNext. Yuck!
8
9This example was adapted from http://msdn.microsoft.com/msdnmag/issues/06/00/C20/default.aspx
10"""
11
12
13class Node<of T> where T must be IComparable<of T>
14
15    cue init(item as T)
16        .init(item, nil, nil)
17
18    cue init(item as T, left as Node<of T>?, right as Node<of T>?)
19        base.init
20        _item = item
21        _left = left
22        _right = right
23
24    pro left from var as Node<of T>?
25
26    pro right from var as Node<of T>?
27
28    get item from var as T
29
30    def compareTo(node as Node<of T>) as int
31        # this method enables comparison operators in Cobra like "a < b" where a and b are Nodes
32        return .item.compareTo(node.item)
33
34    def toString as String is override
35        return '[.typeOf.name](item=[.item])'
36
37    def dump
38        print this stop
39        if _left, print ' left:', _left stop
40        if _right, print ' right:', _right stop
41        print
42        if _left, _left.dump
43        if _right, _right.dump
44
45
46class BinaryTree<of T> where T must be IComparable<of T>
47
48    cue init(root as Node<of T>)
49        base.init
50        _root = root
51
52    pro root from var as Node<of T>
53   
54    def add(items as vari T)
55        for item in items, .add(item)
56   
57    def add(item as T)
58        _add(Node<of T>(item), _root)
59   
60    def _add(newNode as Node<of T>, root as Node<of T>)
61        if newNode > root
62            right = root.right
63            if right
64                _add(newNode, right)
65            else
66                root.right = newNode
67        else if newNode < root
68            left = root.left
69            if left
70                _add(newNode, left)
71            else
72                root.left = newNode
73
74    get inOrder as IEnumerable<of T>
75        return _scanInOrder(_root, 0)
76
77    def _scanInOrder(node as Node<of T>?, level) as IEnumerable<of T>
78        if node
79            if node.left
80                for item in _scanInOrder(node.left to !, level+1)
81                    yield item
82            yield node.item
83            if node.right
84                for item in _scanInOrder(node.right to !, level+1)
85                    yield item
86
87
88class Program
89
90    def main
91        tree = BinaryTree<of int>(Node<of int>(0))
92        tree.add(4, 6, 2, 7, 5, 3, 1)
93        values = List<of int>()
94        for value in tree.inOrder
95            # print value
96            values.add(value)
97        assert values == [0, 1, 2, 3, 4, 5, 6, 7]
Note: See TracBrowser for help on using the browser.