Iterator Pattern Code Review
Code Download
- Download Description:iterator pattern download
- .NET Framework:3.5
- .NET Language:C#
- Date Published:2009-07-01
- Download Size:11 KB
Family Tree Structure
Define the Main Tree Object
Define the Tree class which contains the methods required to iterate through the family tree structure.
class Tree
{
Node m_root;
public Tree(Node head)
{
this.m_root = head;
}
public IEnumerable<Person> Preorder
{
get
{
return this.ScanPreorder(this.m_root);
}
}
private IEnumerable<Person> ScanPreorder(Node root)
{
yield return(root.Data);
if (root.Child != null)
{
foreach (Person p in ScanPreorder(root.Child))
{
yield return (p);
}
}
if (root.Next != null)
{
foreach (Person p in ScanPreorder(root.Next))
{
yield return (p);
}
}
}
public IEnumerable<Person> Where(Func<Person, Boolean> filter)
{
foreach (Person p in this.ScanPreorder(this.m_root))
{
if (filter(p) == true)
{
yield return (p);
}
}
}
}
The ScanPreorder() method is the main method for transvering the tree and uses recursion to iterate from the
root node to the left node and then to the right node for each node in the tree.
For the root node the method yields the data at that node, and for the left and right nodes, it yields a node
to the enumerator. This node will act as the root node and the iteration will start again.
In this way, the entire tree is transversed from left to right and top to bottom.
The Where() method acts as another enumerator, which also calls ScanPreorder() method but filters out the required
Person objects according to the delegate supplied. The type of the delegate is Func <Person,bool>, meaning it takes a Person as a
parameter on each iteration, and returns a boolean value.
The Tree class does not implement the IEnumerable<T> interface so in order to use LINQ functionality the Where()
method was defined.
Define the Node and Person Objects
The Node class (object) represents the definition of a node in the tree structure.
class Node
{
public Node Child { get; set; }
public Node Next { get; set; }
public Person Data { get; set; }
public Node(Person data, Node child, Node next)
{
this.Data = data;
this.Child = child;
this.Next = next;
}
}
The Child property represents the first child node of the current node. The Next property represents the node to the right
of the current node. The Data property represents the data stored for a particular node.
The Person class (object) represents the custom properties required for a person stored in the tree structure.
class Person
{
public String Name { get; set; }
public Int32 Birth { get; set; }
public Person(String name, Int32 birth)
{
this.Name = name;
this.Birth = birth;
}
public override string ToString()
{
return (String.Format("[{0}, {1}]", this.Name, this.Birth));
}
}
Use the Iterator Pattern
The Program class creates the family tree structure and stores this in a variant variable, which will at runtime be
converted to a Tree type.
class Program
{
static void Main(string[] args)
{
var family = new Tree(
new Node(new Person("Tom", 1950),
new Node(new Person("Peter", 1976),
new Node(new Person("Sarah", 2000), null,
new Node(new Person("James", 2002), null, null)),
new Node(new Person("Robert", 1978), null,
new Node(new Person("Mark", 1982),
new Node(new Person("Carrie", 2005), null, null),
null))),
null)
);
Console.WriteLine("Full Family");
foreach (Person p in family.Preorder)
{
Console.Write("{0} ", p);
}
Console.WriteLine("\n");
var selection = from p in family
where p.Birth > 1980
orderby p.Name
select p;
Console.WriteLine("Born after 1980 in alpha order");
foreach (Person p in selection)
{
Console.Write("{0} ", p);
}
Console.WriteLine("\n");
Console.Read();
}
}
The code transverses through the Tree structure and displays all the nodes. Finally, using LINQ syntax the family tree
is filtered by birth year and results displayed.