Emre Can Serteli
Emre Can Serteli

Reputation: 389

How to iterate and sum numeric values stored in children objects to the parent object in a tree-like data

I have a C# object which may parent itself in order to create a tree-like data structure.

public class AssetType
{
    public long? Id { get; set; }
    public string Definition { get; set; }
    public int AssetCount { get; set; }
    public long? ParentId { get; set; }
    public ICollection<AssetType> Children { get; set; }
}

I succesfully populated the data and I have a collection of root AssetTypeTree objects with children. Now, what I need is to sum the AssetCount value of every children to their parent iteratively. For example my initial data may be as follows:

-ELECTRONICS -> AssetCount: 0
  +COMPUTERS -> AssetCount: 0
    *PERSONAL COMPUTERS -> AssetCount: 5
    *SERVERS -> AssetCount: 3
  +PRINTERS -> AssetCount: 2
-FURNITURES -> AssetCount: 0
  +TABLES -> AssetCount: 4

Here, the AssetCount values are correct in the leaf nodes. But I need to also populate the values of the parent nodes. Here, COMPUTERS should have a count of 8, ELECTRONICS should be 10 and FURNITURES should be 4. Depth of nodes may differ and also non-leaf nodes may also have a initial count value other than 0.

It should be possible to write a recursive iteration of some sort but I couldn't wrap my head around this really.

Upvotes: 0

Views: 235

Answers (2)

hijinxbassist
hijinxbassist

Reputation: 4591

A recursive function should do the trick nicely. Here is something i typed up real quick. Make sure there is no circular loops, as i did not check for that.

private int GetAssetCount(AssetType asset)
{
    var assetCount = 0;

    if (asset.Children != null)
    {
        foreach (var child in asset.Children)
        {
            child.AssetCount = GetAssetCount(child);
            assetCount += child.AssetCount;
        }
    }
    else
    {
        assetCount = asset.AssetCount;
    }

    return assetCount;
}

Sanity Check

private void TestAssetRecursion()
{
    var asset0 = new AssetType()
    {
        AssetCount = 0
    };
    var asset1 = new AssetType()
    {
        AssetCount = 0
    };
    var asset2 = new AssetType()
    {
        AssetCount = 0
    };
    var asset3 = new AssetType()
    {
        AssetCount = 3
    };
    var asset4 = new AssetType()
    {
        AssetCount = 4
    };

    asset0.Children = new AssetType[] { asset1 };
    asset1.Children = new AssetType[] { asset2 };
    asset2.Children = new AssetType[] { asset3, asset4 };

    asset0.AssetCount = GetAssetCount(asset0);
}

Upvotes: 1

jdweng
jdweng

Reputation: 34421

Try following :

   class Program
   {
       static void Main(string[] args)
        {
            AssetType root = new AssetType();
            AssetType.AddCount(root);
        }
    }
    public class AssetType
    {
        public long? Id { get; set; }
        public string Definition { get; set; }
        public int AssetCount { get; set; }
        public long? ParentId { get; set; }
        public ICollection<AssetType> Children { get; set; }

        public static int AddCount(AssetType parent)
        {
            foreach (AssetType child in parent.Children)
            {
                parent.AssetCount += AddCount(child); 
            }
            return parent.AssetCount;
        }
    }

Upvotes: 1

Related Questions