I have an object something like this...
type
TMyObject = class(TObject)
private
FParent: TMyObject;
FChildren: TObjectList<TMyObject>;
function GetChildren(const Index: Integer): TMyObject;
public
constructor Create(AParent: TMyObject);
destructor Destroy; override;
function AddChild: TMyObject;
procedure DeleteChild(const Index: Integer);
function ChildCount: Integer;
property Children[const Index: Integer]: TMyObject read GetChildren; default;
end;
(There's much more but this is the fundamental idea)
This allows a simple parent/child relationship between objects, a hierarchy. One is the root, which contains a hierarchy of more.
All this is fine, except I also need to iterate a complete list of all these objects, regardless of hierarchy.
var
Node: TMyObject;
for X := 0 to AllNodes.Count-1 do begin
Node := AllNodes[X];
//Do something with `Node`...
end;
Naturally, I could just create an object list and maintain both at the same time...
FAllObjects: TObjectList<TMyObject>;
However, this is redundant. Every instance of TMyObject would have to be added/deleted to each structure at the same time. I'd like to get rid of requiring one master list, and only use the hierarchy objects. But I don't know how I could iterate all the objects without following the recursive hierarchy. For example, something as simple as getting a total count of all these items.
How can I maintain such an object hierarchy (which I can iterate all items in one single loop) without having to maintain two separate redundant structures?
For example, the TTreeView.Items has the behavior I'd like. You can use Items.Count and Items[Index] to iterate all items, or you can recursively iterate the tree hierarchy.
In a standard
TTreeView, the best way to iterate through all of its nodes in a "linear" fashion from top to bottom is to utilize theTTreeNode.GetNext()method in awhileloop, eg:In your custom node list, you can implement a similar iteration by implementing an Enumerator that can be used with a
for..inloop, which was introduced in Delphi 2007. See Embarcadero's documentation for more details:Declarations and Statements (Delphi): Iteration Over Containers Using For statements
For example:
Behind the scenes, the compiler will generate code similar to the following:
If you are using Delphi 2006 or earlier,
for..inis not available, so you will have to use the abovewhileloop explicitly instead.