Recursively count child objects, display results at heading level.

Hi All,

I need to produce a view that contains an attrDXL column that puts some totals against all Level x headings, by counting all objects below that heading (perhaps also only count if obj."Object Text" contains a TBD etc.)

e.g. suppose the Module looked like this:

1. Functional Requirements
1.1 System XY
Some requirement #1
Some requirement #2
Some requirement #4
Some requirement #51
1.2 System ABC
Some Requirement #200
Some Requirement #230
Some Requirement #265

The resultant view (showing just headings) with attrDXL column would look like this:

1. Functional Requirements 7
1.1 System XY 4
1.2 System ABC 3
I remember someone posted some really neat (about 7 lines!) of code back in the Telelogic Forum days, that from memory, made use of a "for obj in obj do {}" contruct which basically recursively drilled down and counted the number of leaf objects and put the totals in a column, however I've been unable to find the code snippet in our archives. Would anyone know how to achieve this? I know the code involved a count and a check if the object was a parent.

I did try to write the pseudocode but just ended up getting confused!

Any help would be much appreciated!

Rob.
rl4engi - Thu May 27 09:56:01 EDT 2010

Re: Recursively count child objects, display results at heading level.
rl4engi - Thu May 27 11:52:06 EDT 2010

Edit: I've sussed it, it had a recursive function call, I remembered there was something quirky about it. I'm repeating the code in case it comes in handy for other users. It's a very quick and easy way of gathering metrics, particularly if you start introducing conditionals for the counts.

int count = 0
Object o
 
string countObjs(Object obj)
{
   for o in all obj do // For each child of obj
   {
      if (leaf (o))
      {
         count ++
      }
      else // Is a parent, so call countObjs 
      {
         countObjs (o)
      }
   }
   return count ""
}
 
if (!leaf (obj))
{ 
   obj.attrDXLName = countObjs(obj)
}
else
{
   obj.attrDXLName = ""
}

Re: Recursively count child objects, display results at heading level.
llandale - Thu May 27 15:27:39 EDT 2010

rl4engi - Thu May 27 11:52:06 EDT 2010

Edit: I've sussed it, it had a recursive function call, I remembered there was something quirky about it. I'm repeating the code in case it comes in handy for other users. It's a very quick and easy way of gathering metrics, particularly if you start introducing conditionals for the counts.

int count = 0
Object o
 
string countObjs(Object obj)
{
   for o in all obj do // For each child of obj
   {
      if (leaf (o))
      {
         count ++
      }
      else // Is a parent, so call countObjs 
      {
         countObjs (o)
      }
   }
   return count ""
}
 
if (!leaf (obj))
{ 
   obj.attrDXLName = countObjs(obj)
}
else
{
   obj.attrDXLName = ""
}

This doesn't look right at all. Surely each Heading object wants to set its count to zero before iniating another recursive call. Declaring 'o' globally surely will cause it to fail.

I didn't actually try to run the following:

int countObjs(Object obj)
{      // Count all leaf objects under this object
        // RECURSION Enabled
   if (null(obj))               return(0)
   if (isDeleted(obj))          return(0)
   if (table(obj) or row( obj)) return(0)
   if (cell (obj) or leaf(obj)) return(1)
                // Must be heading object
   int  Count = 0
   Object o
 
   for o in all obj do // For each child of obj
   {
      Count = Count + countObjs(o)      // ** RECURSION **
   }
   return (Count)
}     // end countObjs()
 
int Count = countObjs(obj)
if (Count != 0)                 //-
then obj.attrDXLName = Count ""
else obj.attrDXLName = ""


Oops. Of course I really mean:

 

else obj.attrDXLName = " "


as setting it to the null string will initiate thrashing of recaculation; wheres setting it to a space does not.

 

 

  • Louie