2

I am attempting to determine which data structure I should use for the following information:

        ("Water", 100F, 0F, 0F, 0F, 0F, 0F, 0F, 0F, 0F, 0F, "");
        ("Tuna", 60F, 184F, 30F, .01F, .001F, .064F, .05F, 0F, .011F, .05F, "");
        ("Chicken Breast", 62F, 197F, 30F, .01F, .001F, .027F, .07F, 0F, .013F, .084F, "");
        ("Cheese", 37F, 406F, 24F, .01F, .000F, .027F, .64F, 0F, 0F, .1F, "");
        ("Beef Sausage", 54F, 320F, 12F, .01F, .001F, .013F, .911F, 0F, .003F, .058F, "");
        ("Boiled Eggs", 75F, 155F, 12.5F, .01F, .001F, .010F, .124F, 0F, 0F, .373F, "");
        ("Broccoli", 89F, 34F, 3F, 2.4F, 0F, .021F, .033F, .089F, 0F, 0F, "");

Essentially, these are types of food and certain constituent nutritional values and the string on the end is for additional comments.

I want to be able to call the name of the food elsewhere in the code (i.e. NutritionalData("Tuna") and have it return the nutritional data previously stored in the data structure.

When replying, please bear in mind I am a novice programmer. I looked into Array but that seemed limited to one data type, and these need to be a combination of strings and floats. The first entry will be unique (there won't be two entries for "Tuna", for example), so I was wondering if the Dictionary data type might be best, but I don't know much about it.

Or would this be best as a new class like the following:

class FoodItem
    {
        string Name;
        float Hydration;
        float Calories;
        float Protein;
        float Fiber;
        float Iron;
        float Magnesium;
        float Sodium;
        float VitaminC;
        float Niacin;
        float Cholesterol;
        string Special;
    }

Here is the edited code, Not sure if it works because I haven't figured out how to call a method from outside the class. Yay for self-education.

class MakeFoodDictionary
{
    public Dictionary<string, FoodItem> foodDictionary = new Dictionary<string, FoodItem>();

    public struct FoodItem
    {
        public string Name;
        public float Hydration;
        public float Calories;
        public float Protein;
        public float Fiber;
        public float Iron;
        public float Magnesium;
        public float Sodium;
        public float VitaminC;
        public float Niacin;
        public float Cholesterol;
        public string Special;
    }

    public FoodItem TempFoodItem;

    public void CreateAllFoods()
    {
        CreateNewFoodItem("Water", 100F, 0F, 0F, 0F, 0F, 0F, 0F, 0F, 0F, 0F, "");
        CreateNewFoodItem("Tuna", 60F, 184F, 30F, .01F, .001F, .064F, .05F, 0F, .011F, .05F, "");
        CreateNewFoodItem("Chicken Breast", 62F, 197F, 30F, .01F, .001F, .027F, .07F, 0F, .013F, .084F, "");
        CreateNewFoodItem("Cheese", 37F, 406F, 24F, .01F, .000F, .027F, .64F, 0F, 0F, .1F, "");
        CreateNewFoodItem("Beef Sausage", 54F, 320F, 12F, .01F, .001F, .013F, .911F, 0F, .003F, .058F, "");
        CreateNewFoodItem("Boiled Eggs", 75F, 155F, 12.5F, .01F, .001F, .010F, .124F, 0F, 0F, .373F, "");
        CreateNewFoodItem("Broccoli", 89F, 34F, 3F, 2.4F, 0F, .021F, .033F, .089F, 0F, 0F, "");
        CreateNewFoodItem("Dry Oats", 8F, 389F, 17F, 10.6F, .005F, .177F, .002F, 0F, .001F, 0F, "");
        CreateNewFoodItem("Ale", 91F, 37F, .2F, 0F, 0F, .007F, .013F, 0F, .001F, 0F, "Inebriation");
        CreateNewFoodItem("Salted Beans", 67F, 127F, 8.67F, 6.4F, .003F, .045F, .238F, .001F, .001F, 0F, "");
        CreateNewFoodItem("Bread", 32F, 278F, 8.4F, 6F, .003F, .081F, .346F, 0F, .004F, 0F, "");
        CreateNewFoodItem("Turnips", 92F, 28F, .9F, 1.8F, 0F, .011F, .067F, .021F, 0F, 0F, "");
        CreateNewFoodItem("Salted Pork", 11F, 748F, 5F, 0F, 0F, .007F, 2.684F, 0F, .002F, .086F, "");
        CreateNewFoodItem("Cabbage", 92F, 25F, 1F, 1.9F, 0F, .012F, .018F, .037F, 0F, 0F, "");
        CreateNewFoodItem("Dried Blueberries", 15F, 317F, 2.5F, 7.5F, .001F, .018F, .003F, .024F, .001F, 0F, "");
        //AddNewFoodToArray(string Name, float Hydration, float Calories, float Protein, float Fiber, float Iron, float Magnesium, float Sodium, float VitaminC, float Niacin, float Cholesterol); 
        TempFoodItem = TempFoodItem;
    }

    public void CreateNewFoodItem(string _Name, float _Hydration, float _Calories, float _Protein, float _Fiber, float _Iron, float _Magnesium, float _Sodium, float _VitaminC, float _Niacin, float _Cholesterol, string _Special)
    {
        TempFoodItem = new FoodItem
        {
            Name = _Name,
            Hydration = _Hydration,
            Calories = _Calories,
            Protein = _Protein,
            Fiber = _Fiber,
            Iron = _Iron,
            Magnesium = _Magnesium,
            Sodium = _Sodium,
            VitaminC = _VitaminC,
            Niacin = _Niacin,
            Cholesterol = _Cholesterol,
            Special = _Special
        };
        foodDictionary.Add(_Name, TempFoodItem);
    }
}
| improve this question | | | | |
  • 3
    The class is the way to go. – Robert Harvey Oct 1 '15 at 17:06
  • Is there any chance of adding new nutrients later? – durron597 Oct 1 '15 at 17:19
  • @durron597 There will not be new nutrients added later in my plan. These were the best indicators for what I needed and they will not be changing. – Fixer Oct 1 '15 at 17:29
3

Yes, use FoodItem.

You can store them in a List<>, then use linq (very cool) to find the one you want:

List<FoodItem> myFoodItems = new List<FoodItem>();

/* populate myFoodItems the hard way */
myFoodItems.Add(new FoodItem{
    Name = 'tuna',
    Hydration = 60F,
    /* rest of items skipped - you get the idea */
});

FoodItem tuna = myFoodItems.Find(e => e.Name == "tuna");

If you have a zillion of FoodItems, you can also store them in a dictionary by name:

Dictionary<string, FoodItem> foodDict = new Dictionary<string, FoodItem>();
/* initialize the hard way */
myfoodItem = new FoodItem{
    Name = "tuna",
    Hydration = 60F,
    /* and so on */
};
foodDict.Add("tuna", myfoodItem);

FoodItem tuna = foodDict["tuna"];

The duplication of FoodItem.Name and the key to the dictionary is OK - leave it there (it will save time debugging).

This is initializing the hard way - you really should store this data in a file somewhere then read it in when the program starts - that will make it easier to add new items and correct errors. The code for that is much longer than this.

| improve this answer | | | | |
  • That code you 'skipped'.... can you put that in? That seems to be with what I am having a problem. I can't get the syntax down. – Fixer Oct 1 '15 at 17:25
  • @ Dan Pichelman I hope I did it right. I put the edited code into the OP. Now to figure out how to call it from another class. – Fixer Oct 2 '15 at 14:03
  • What does this part do: FoodItem tuna = foodDict["tuna"]; – Fixer Oct 2 '15 at 15:41
  • The last line in both of my examples just finds the tuna entry. The first one uses linq to locate the entry in the list with a Name of "tuna". The second one accesses the dictionary. – Dan Pichelman Oct 2 '15 at 15:58
0

Go further

public class NutritionalData
{
    public string Type {get;set;}
    public float Grams {get;set;}
}

public class FoodItem
{
   public string Name {get;set;}
   public List<NutritionalData> NutritionalContent {get;set;}
   public string Description {get;set;}
}
| improve this answer | | | | |
  • I think I understand what you are meaning, but those aren't percentages. Those are actual measurements of grams of various nutrients. How does that affect what you are doing there? – Fixer Oct 1 '15 at 17:28
  • 1
    @Phicksur s/Percent/Amount/ and its all the same. Its just the name of the field. – user40980 Oct 1 '15 at 18:03
  • Such a solution can be ok in certain contexts, but it has one drawback: each food item contains the same nutrient names again and again (or if the names are not identical, or not the expected ones, the structure becomes invalid). One can overcome this, for example, by using an enum for the different types of nutrients and use that as in index into a List<float>instead of a List<NutritionalData>. – Doc Brown Oct 1 '15 at 18:58
  • Programmers is about conceptual questions and answers are expected to explain things. Throwing code dumps instead of explanation is like copying code from IDE to whiteboard: it may look familiar and even sometimes be understandable, but it feels weird... just weird. Whiteboard doesn't have compiler – gnat Oct 1 '15 at 20:34
  • 2
    @Ewan: "enums" (or constants) are mostly the opposite of magic numbers. In a database, the "meta information" of how a specific column is named is typically separated from the data and not repeated in every row. Your model above will allow every row to have different column names apart from every other row. But as I wrote, your solution is not wrong. – Doc Brown Oct 2 '15 at 8:34
-1

It may be more efficient to store all of the data in an external database and import the data and call each item needed using a loop.

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.