Reputation: 21
I'm using ASP.NET Webforms, and have several C# strings representing parent and child categories. The strings are on this form:
parent>child
And i would like to split the string and list each child under the correct parent. My end goal is to be able to output these parent and child categories on my webpage like this:
<li>Parent
<ul>Child 1</ul>
<ul>Child 2</ul>
</li>
For example, if I have the following strings:
string cat1 = "fish>shark";
string cat2 = "fish>nemo";
string cat3 = "birds>eagle";
string cat4 = "birds>hawk";
I want to display them on my page like this:
What would be the best approach to accomplish this?
Upvotes: 1
Views: 377
Reputation: 41665
I'm not sure whether you simply want to create the markup as a string or if you'd like to do things with the list and its children as ASP.NET controls. At any rate, here's an option:
HtmlGenericControl rootUl, parentLi, childLi;
// create the html list
rootUl = new HtmlGenericControl("ul");
// our name-control mapping
var controls = new Dictionary<string, HtmlGenericControl>();
// our data
var items = new[]{
"fish>shark>mako",
"fish>shark>tiger",
"fish>clown fish>nemo",
"birds>eagle>bald eagle",
"birds>hawk",
};
// loop through the data items
foreach (var item in items)
{
// split by the greater-than symbol
var names = item.Split('>');
// if we don't already have a control for the topmost parent...
if (!controls.TryGetValue(names[0], out parentLi))
{
// create the control and store it in our mapping
controls[names[0]] = parentLi = new HtmlGenericControl("li")
{
InnerText = names[0]
};
// add it to the html list
rootUl.Controls.Add(parentLi);
}
// loop through the remaining parts
foreach (var name in names.Skip(1))
{
// if the parent doesn't have a list-child...
if (parentLi.Controls.Count == 1)
{
// add an html list child to the parent
parentLi.Controls.Add(new HtmlGenericControl("ul"));
}
// if we don't already have a control for the child...
if (!controls.TryGetValue(name, out childLi))
{
// create the control
controls[name] = childLi = new HtmlGenericControl("li"){
InnerText = name
};
}
// add the child to the parent's html list
parentLi.Controls[1].Controls.Add(childLi);
// keep a reference to the child for further nesting
parentLi = childLi;
}
}
// add the html list to the form
form1.Controls.Add(rootUl);
This results in the following output:
<ul>
<li>fish
<ul>
<li>shark
<ul>
<li>mako</li>
</ul>
</li>
<li>nemo</li>
</ul>
</li>
<li>birds
<ul>
<li>eagle
<ul>
<li>bald eagle</li>
</ul>
</li>
<li>hawk</li>
</ul>
</li>
</ul>
Upvotes: 2
Reputation: 1291
I would create a hash table of lists:
Dictionary<string, List<string>> data;
and then I would loop through all the strings and put them in the structure:
foreach (var pair in stringList)
{
string[] split = pair.split('>');
if (data.ContainsKey(split[0]) == false)
data.Add(split[0], new List<string>());
data[split[0]].Add(split[1]);
}
Something like that should work. I haven't compiled it so you may have to make some tweaks, but it should give you the basic idea.
To output the data:
foreach (string parent in data.Keys)
{
// Output parent data
foreach (string child in data[parent])
{
// Output each child.
}
}
Upvotes: 3