Search code examples
c#arraysmultidimensional-arrayassociative-array

Multidimensional Associative Arrays in C#


Started getting into C# from JS and PHP. I am getting used to the strict use of data types and I am struggling to figure out how to declare multidimensional associative array of different data types.

Like for example in PHP one would probably do something like this

 $roomDiscount["apartment"][0]["minDaysOfStay"] = 10;
 $roomDiscount["apartment"][0]["discount"] = 0.3;

 $roomDiscount["apartment"][1]["minDaysOfStay"] = 15;
 $roomDiscount["apartment"][1]["discount"] = 0.35;

 $roomDiscount["apartment"][2]["minDaysOfStay"] = 16;
 $roomDiscount["apartment"][2]["discount"] = 0.5;

 $roomDiscount["presidential suite"][0]["minDaysOfStay"] = 10;
 $roomDiscount["presidential suite"][0]["discount"] = 0.1;

 $roomDiscount["presidential suite"][1]["minDaysOfStay"] = 15;
 $roomDiscount["presidential suite"][1]["discount"] = 0.15;

 $roomDiscount["presidential suite"][2]["minDaysOfStay"] = 16;
 $roomDiscount["presidential suite"][2]["discount"] = 0.2;

So far I have been struggling with Dictionaries

private static void SkiTripWithDictionariesArrays()
        {
            int daysOfStay = int.Parse(Console.ReadLine());
            string typeOfAccomodation = Console.ReadLine().ToLower().Trim();
            string review = Console.ReadLine().ToLower().Trim();

            Dictionary<string, double> roomPrices = new Dictionary<string, double>();
            Dictionary<string, object> roomDiscounts = new Dictionary<string, object>(); // <---- thats the bugger
            Dictionary<string, double> reviewAdjustment = new Dictionary<string, double>();

           
            //populate room prices
            roomPrices.Add("room for one person", 18);
            roomPrices.Add("apartment", 25);
            roomPrices.Add("president apartment", 35);

        }

Solution

  • Your current PHP code is like this:

    $roomDiscount["apartment"][0]["minDaysOfStay"] = 10;
    

    It is close to this kind of structure in C#:

    Dictionary<string, List<Dictionary<string, double>>>
    

    Declaring such an object probably isn't a good way of going about it. Instead you should define class objects instead. The example I give below is for illustrative purposes only, and isn't necessarily the best way to do this (there are many different approaches to this situation):

    public class RoomDiscount
    {
        public int MinDaysOfStay {get;set;}
        public double Discount {get;set;}
    }
    
    public class RoomDiscounts
    {
        public List<RoomDiscount> DiscountBands {get;set;}
    }
    

    Usage:

    Dictionary<string, RoomDiscounts> discountDetails = new Dictionary<string, RoomDiscounts>();
    discountDetails["apartment"] = new RoomDiscounts {
        DiscountBands = new List<RoomDiscount> {
            new RoomDiscount {
                MinDaysOfStay = 10,
                Discount = 0.3
            },            
            new RoomDiscount {
                MinDaysOfStay = 15,
                Discount = 0.35
            },            
            new RoomDiscount {
                MinDaysOfStay = 16,
                Discount = 0.5
            }
        }
    };
    
    string room = "apartment";
    int daysOfStay = 26;
    double discount = discountDetails[room].DiscountBands.OrderByDescending(b => b.MinDaysOfStay).FirstOrDefault(b => daysOfStay >= b.MinDaysOfStay)?.Discount ?? 0;
    

    Again, this is just an example of one way you could organise your data in a more strongly-typed fashion. Note that this will throw an exception if the room type isn't defined, so you could use TryGetValue to retrieve the details from the dictionary.