Reputation: 1352
I am working on a program where each item can hold an array of items (i'm making a menu, which has a tree-like structure)
currently i have the items as a list, instead of an array, but I don't feel like I'm using it to its full potential to simplify code. I chose a list over a standard array because the interface (.add, .remove, etc...) makes a lot of sense.
I have code to search through the structure and return the path of the name (i.e. Item.subitem.subsubitem.subsubsubitem). Below is my code:
public class Item
{
//public Item[] subitem; <-- Array of Items
public List<Item> subitem; // <-- List of Items
public Color itemColor = Color.FromArgb(50,50,200);
public Rectangle itemSize = new Rectangle(0,0,64,64);
public Bitmap itemBitmap = null;
public string itemName;
public string LocateItem(string searchName)
{
string tItemName = null;
//if the item name matches the search parameter, send it up)
if (itemName == searchName)
{
return itemName;
}
if (subitem != null)
{
//spiral down a level
foreach (Item tSearchItem in subitem)
{
tItemName = tSearchItem.LocateItem(searchName);
if (tItemName != null)
break; //exit for if item was found
}
}
//do name logic (use index numbers)
//if LocateItem of the subitems returned nothing and the current item is not a match, return null (not found)
if (tItemName == null && itemName != searchName)
{
return null;
}
//if it's not the item being searched for and the search item was found, change the string and return it up
if (tItemName != null && itemName != searchName)
{
tItemName.Insert(0, itemName + "."); //insert the parent name on the left --> TopItem.SubItem.SubSubItem.SubSubSubItem
return tItemName;
}
//default not found
return null;
}
}
My question is if there is an easier way to do this with lists? I've been going back and forth in my head as to whether I should use lists or just an array. The only reason I have a list is so that I don't have to make code to resize the array each time I add or remove an item.
Upvotes: 2
Views: 1749
Reputation: 117124
Lists sound great. I'd suggest a variation on your definition though. Try creating your class like this:
public class Item : List<Item>
{
public string Name;
}
If you make Item
inherit from List<Item>
you automatically make it a tree without requiring the subitem
field.
Here's my full version of your class:
public class Item : List<Item>
{
public string Name;
private List<Item> LocateItems(string searchName)
{
if (this.Name == searchName)
return (new [] { this }).ToList();
var result =
this
.Select(s => s.LocateItems(searchName))
.Where(x => x !=null && x.Count > 0)
.FirstOrDefault();
if (result != null)
result.Add(this);
return result;
}
public string LocateItem(string searchName)
{
var items = this.LocateItems(searchName);
if (items == null)
return null;
else
return String.Join(".", items.Select(i => i.Name).Reverse());
}
}
The method LocateItems
returns the list of Item
starting with the Item
that matched and followed by all of the parent Item
instances up to and including the root.
I tested with this code:
var foos = new Item() { Name = "Foo" };
var bars = new Item() { Name = "Bar" };
var qazs = new Item() { Name = "Qaz" };
var wees = new Item() { Name = "Wee" };
foos.Add(bars);
bars.Add(qazs);
foos.Add(wees);
Console.WriteLine(foos.LocateItem("Wee"));
Console.WriteLine(foos.LocateItem("Qaz"));
Console.WriteLine(foos.LocateItem("Bar"));
Console.WriteLine(foos.LocateItem("Foo"));
And I got these results:
Foo.Wee
Foo.Bar.Qaz
Foo.Bar
Foo
Upvotes: 2
Reputation: 304
I would suggest lists. Since adding/removing items to an array reallocates memory, for a dynamic collection of items (which I assume is your case) lists usually have better performance overall. You might want to take a look at:
Array versus List<T>: When to use which?
Upvotes: 1
Reputation: 5695
Using a list in this case is perfectly acceptable. An array would make a better choice if performance was an issue - if it is, arrays are slightly faster but much less flexible as you've discovered.
One thing that people don't talk about enough is that simplicity is a great basis for structuring code. If it's simpler to write and maintain using lists than arrays, then (all else being equal) using lists is perfectly correct.
Upvotes: 2