1

I looked at this article to see if I could use that as a starting point, but I don't see it addressing my particular problem. C#: N For Loops

I have the following code:

int criteriaCount = rule.SearchCriteria.Criteria.Count();
string criteria = "";
        for (int i = 0; i < criteriaCount; i++)
        {
            if (rule.SearchCriteria.Criteria[i].Criteria.Count() > 0)
            {
                criteria += string.Format("({0}" + System.Environment.NewLine, rule.SearchCriteria.Criteria[i].Display);
                criteria += string.Format("{0})" + System.Environment.NewLine, rule.SearchCriteria.Criteria[i].Criteria[i].Display);
            }
            else
            {
                criteria += string.Format("[{0}]" + System.Environment.NewLine, rule.SearchCriteria.Criteria[i].Display);
            }
        }

To explain a little, you have in SearchCriteria and Array of Criteria[]. I can loop through this and grab the follow I need from each Criteria object as you can see I am doing.

I am also looking at the second level deep, so SearchCriteria.Criteria[n].Criteria[n] and I can put a for loop their and grab any nested values there as well.

The part I cannot figure out is how can I account for a variable number of nested Criteria objects? I could potentially have this:

SearchCriteria.Criteria[n].Criteria[n] ... (repeat a hundred times)... .Criteria[n]

So it can have potentially an infinite number of nested objects, and an infinite number of sibling objects (Criteria[0], Criteria[1] ... Criteria[100000] is what I mean).

Is there a way I can loop through all this? I have heard the a recursive loop may be the answer, and I vaguely understand that concept, but what I don't know is how can I get the number of children and siblings?

Community
  • 1
  • 1
ledgeJumper
  • 3,560
  • 14
  • 45
  • 92
  • Please, store the value of `Count()` into a variable... you don't need to call it so often when you are in no danger of modifying the contents. – TheZ Aug 10 '12 at 20:33
  • Changed the code, this is just a rough, trying to get it to work sample, thus me just calling it every time. – ledgeJumper Aug 10 '12 at 20:35

3 Answers3

5

The basic concept for a recursive loop is defined below. You will be limited to the space available on the stack.

private String GetSearchCriteria(Citeria root) {

  String result = root.Display;

  foreach (Criteria child in root.Criteria) {
    result += GetSearchCriteria(child);
  }

  return result;

}
Sam Axe
  • 33,313
  • 9
  • 55
  • 89
2

Use recursion, and in your case you may use something like this...

        private static string DisplayCriteria(Criteria criteriaObject)
        {
            string criteria = "";
            foreach(Criteria c in criteriaObject)
            {
                if (c.Criteria.Count() > 0)
                {
                    criteria += string.Format("({0}" + System.Environment.NewLine, c.Display);
                    criteria += string.Format("{0})" + System.Environment.NewLine, DisplayCriteria(c.Criteria));
                }
                else
                {
                    criteria += string.Format("[{0}]" + System.Environment.NewLine, c.Display);
                }
            }
            return criteria;
        }

        // your code  ...
        DisplayCriteria(rule.SearchCriteria.Criteria);
        // your code  ...

I am not sure about the new lines there, you can add/remove them later

Vlad
  • 2,475
  • 21
  • 32
  • Thanks, this one actually makes the most sense to me. Gonna have to sit down and go through it all since my brain is having difficulties grasping what I need to do here. I kind of get it, I just need to think through how to recursive go through all the children and siblings, and what order to do that. Great start though, thanks! – ledgeJumper Aug 10 '12 at 21:06
1

You need to make your method into a "Recursive Method"...a method that calls itself to handle unlimited nesting, such as this:

public string ParseCriteria( Criteria criteria ) {
    string result = "(";
    result += criteria.Display;
    foreach( var criteria in criteria.Criteria) {
        result += ParseCriteria( criteria )
    }
    return result;
}

then, something like this in your existing code.

foreach( var criteria in rule.SearchCriteria.Criteria ) {
    string result += ParseCriteria(criteria);
}

string concatentation is not ideal, and my exmaple doesn't format correctly...but hopefully you get the idea.

Kevin Nelson
  • 7,613
  • 4
  • 31
  • 42