- Home /
Unity enum map - how to make it more efficient/clean? Linear line complexity. Best practices.
I'm new to C# and Unity (used it for 2 weeks), and recently I have been bogged down about this problem.
I don't know if it can be made cleaner, but basically I have an enum and struct that maps information about the Food.
public enum Food {
Apple,
Orange,
Pizza
};
public struct CalorieMap {
public int Apple;
public int Orange;
public int Pizza;
}
The method I can think of has the side effect that the number of lines in the function would linearly scale with the number of Food items (could also be a switch statement, but would have same number of lines as if statement).
public int GetCalories(Food food) {
if (food == Food.Apple) return CalorieMap.Apple;
if (food == Food.Orange) return CalorieMap.Orange;
if (food == Food.Pizza) return CalorieMap.Pizza;
return 0;
}
However, I was wondering if it was possible to do something like this which would be more maintainable and clean?
public int GetCalories(Food food) {
return CalorieMap[Food];
}
Of course I could use a Dictionary, but with a struct, is it possible? The reason why I wanted to use the struct is because I initialise/customise the caloric contents in the inspector. If I have 1000 foods, then the first code would be inefficient (would be over 1000 lines) and I would prefer having the one-liner instead. Another problem with using a Dictionary is that the user might have forgotten to set one of the calories for a food item, but I guess I could check that in run-time or something. Although, if using a dictionary is actually best practice, let me know.
I have been trying to think of the best way to solve it and the best practices that would be easy to maintain. Instead of those ints, those could also be a Sprite, or an Object, or any kind of mapping.
Maybe the food has other information, such as portion size, density, etc. Even if I extract it out Foods to classes, it still has linear line complexity for the methods unless there is a special technique I can use in Unity C#.
Thanks in advance!
Answer by Bunny83 · Jul 29, 2018 at 05:09 PM
If you plan to have that many food items i wouldn't recommend to use an enum at all. Just create a FoodItem class like that:
[System.Serializable]
public class FoodItem
{
public string name;
public int calories;
}
And in your actual MonoBehaviour or ScriptableObject just declare a List:
public List<FoodItem> foods;
Now you can setup all fooditems in the inspector. To get easy runtime access you can create a dictionary dynamically:
Dictionary<string, FoodItem> m_FoodItemMap = new Dictionary<string, FoodItem>();
void Awake()
{
foreach(var fi in foods)
m_FoodItemMap.Add(fi,name, fi);
}
It doesn't make much sense to hardcode only a part of the food items but create the rest through serialization. If you want to create them dynamically in the inspector you shouldn't use an enum.
If you prefer to hardcode your food items you probably want to hardcode everything in code. What you initially want is not possible and generally a bad design. Implementing seperate fields for similar things is the wrong approach. Even they have a similar purpose they can't be treated in a generic / abstract way.
If you really want to keep your original code you should use a switch instead of if-else chains. A switch statement is implemented as jumptable while an if-else chain becomes quite expensive with that many statements.
Thanks for the answer! I will go for a similar solution to your suggested for my game. =)
Your answer
Follow this Question
Related Questions
Hashtable(or generic dictionary) vs Enum - when do I use which? 1 Answer
Enum instead of numbers in arrays 1 Answer
hashtable: snapshot out of sync 2 Answers
Map/Dict of Arrays 1 Answer
Var names in Unity javascript 2 Answers