I have a flat list of categories as shown in the following classes
public class FlatCategoryList
{
public List Categories { get; set;
Use a two-pass solution. This assumes the full collection can fit in memory. The first pass scans the list of flat categories, and builds a dictionary of Category, indexed by the ID. The child collections are all empty at this point, and the parent property is null. Then the second pass scans them again, and builds up the child collections and sets the parent property.
Untested code:
var final = new Dictionary();
var rootCategories = new List();
// Pass 1
foreach (var flat in flatList)
{
Category cat = new Category() { ID = flat.ID, Name = flat.Name, parent = null }
cat.Children = new List();
final[flat.ID] = cat;
}
// Pass 2
foreach (var flat in flatList)
{
// find myself -- must exist
var self = final[flat.ID];
// find parent -- may not exist
if (final.ContainsKey(flat.ParentID)
{
var parent = final[flat.ParentID];
parent.Children.Add(self);
self.Parent = parent;
}
else
{
rootCategories.Add(self);
}
}
This will have O(n) running time, since it's two linear scans, with some dictionary lookups, which are O(1).