1

I am trying to create a two dimensional array and I am getting so confused. I was told by a coworker that I need to create a dictionary within a dictionary for the array list but he couldn't stick around to help me.

I have been able to create the first array that lists the the programs like this

+ project 1
+ project 2
+ project 3
+ project 4

The code that accomplishes this task is below-

var PGList = from x in db.month_mapping
             where x.PG_SUB_PROGRAM == SP 
             select x;
             //select x.PG.Distinct().ToArray();

var PGRow = PGList.Select(x => new { x.PG }).Distinct().ToArray();

So that takes care of my vertical array and now I need to add my horizontal array so that I can see the total amount spent in each accounting period. So the final output would look like this but without the dashes of course.

+ program 1-------100---200---300---400---500---600---700---800---900---1000---1100---1200
+ program 2-------100---200---300---400---500---600---700---800---900---1000---1100---1200
+ program 3-------100---200---300---400---500---600---700---800---900---1000---1100---1200
+ program 4-------100---200---300---400---500---600---700---800---900---1000---1100---1200

I have tried to use a foreach to cycle through the accounting periods but it doesn't work. I think I might be on the right track and I was hoping SO could provide some guidance or at the very least a tutorial for me to follow. I have posted the code that I written so far on the second array below. I am using C# and MVC 3. You might notice that their is no dictionary within a dictionary. If my coworker is correct how would I do something like that, I took a look at this question using dictionary as a key in other dictionary but I don't understand how I would use it in this situation.

Dictionary<string, double[]> MonthRow = new Dictionary<string, double[]>();

double[] PGContent = new double[12];

string lastPG = null;

foreach (var item in PGRow)
{
    if (lastPG != item.PG)
    {
        PGContent = new double[12];
    }


    var MonthList = from x in db.Month_Web
                    where x.PG == PG
                    group x by new { x.ACCOUNTING_PERIOD, x.PG, x.Amount } into pggroup
                    select new { accounting_period = pggroup.Key.ACCOUNTING_PERIOD, amount = pggroup.Sum(x => x.Amount) };

    foreach (var P in MonthList)
    {
        int accounting_period = int.Parse(P.accounting_period) - 1;
        PAContent[accounting_period] = (double)P.amount;
        MonthRow[item.PG] = PGContent;
        lastPG = item.PG;
    } 

I hope I have clearly explained my issue, please feel free to ask for any clarification needed as I need to solve this problem and will be checking back often. Thanks for your help!

0

3 Answers 3

1

hope this helps.

// sample data
var data = new Dictionary<string, List<int>>();
data.Add("program-1", new List<int>() { 100, 110, 130 });
data.Add("program-2", new List<int>() { 200, 210, 230 });
data.Add("brogram-3", new List<int>() { 300, 310, 330 });

// query data
var newData = (from x in data
               where x.Key.Contains("pro")
               select x).ToDictionary(v => v.Key, v=>v.Value);

// display selected data
foreach (var kv in newData)
{
    Console.Write(kv.Key);
    foreach (var val in kv.Value)
    {
        Console.Write(" ");
        Console.Write(val.ToString());
    }
    Console.WriteLine();
}

output is:

program-1 100 110 130
program-2 200 210 230
Sign up to request clarification or add additional context in comments.

Comments

1

Don't try to use anonymous types or LINQ projection to create new data types, especially if you're a beginner, you will just get confused. If you want a specialized data type, define one; e.g.:

public class Account
{
    public string Name { get; private set; }
    public decimal[] MonthAmount { get; private set; }

    readonly int maxMonths = 12;

    public Account(string name, ICollection<decimal> monthAmounts)
    {
        if (name == null)
            throw new ArgumentNullException("name");

        if (monthAmounts == null)
            throw new ArgumentNullException("monthAmounts");

        if (monthAmounts.Count > maxMonths)
            throw new ArgumentOutOfRangeException(string.Format(" monthAmounts must be <= {0}", maxMonths));

        this.Name = name;

        this.MonthAmount = new decimal[maxMonths];
        int i = 0;
        foreach (decimal d in monthAmounts)
        {
            this.MonthAmount[i] = d;
            i++;
        }
    }
}

Use instances of this type directly, you do not have to convert them to arrays, dictionaries, lists, or anything else:

var accountPeriods = new List<Account>();
accountPeriods.Add(new Account("program-1", new decimal[] { 1, 2, 3, 4 }));

You can use LINQ or whatever to query or alter instances of your new type:

foreach (Account a in accountPeriods)
    foreach (decimal d in a.MonthAmount)
        DoSomethingWith(d);

That should be enough to get you started.

2 Comments

Thank you so much for your response, I am sorry I have not been able to get back to you sooner but I am trying to make sense of the code you gave me. I am having issues with the foreach because I am getting the data from a Linq to SQL query so I think I have to convert them to a dictionary.
@Goldentp, what does "having issues" mean? You can convert classes like Account to and from LINQ. Please post the definition of month_mapping; if it is from LINQ you can get the definition from the debugger.
0

I want to thank @Ray Cheng and @Dour High Arch for their help but I have figured out another way to accomplish this task and I wanted to post my code so that the next person that is having the same trouble can figure out their problem faster.

Above I split my code into more managable sections to explain my problem as clearly as I could and the code below has all those parts combined so you can see the big picture. This code returns an array that contains the program and the amounts for every month.

public virtual ActionResult getAjaxPGs(string SP = null)
        {

            if (SP != null)
            {


                var PGList = from x in db.month_mapping
                             where x.PG_SUB_PROGRAM == SP 
                             select x;




                var PGRow = PGList.Select(x => new { x.PG }).Distinct().ToArray();

                float[] PGContent = new float[12];




                Dictionary<string,float[]> MonthRow = new Dictionary<string, float[]>();


                foreach (var item in PGRow)
                {

                        PGContent = new float[12];




                    var MonthList = from x in db.month_Web
                                    where x.PG == item.PG
                                    group x by new { x.ACCOUNTING_PERIOD, x.PG, x.Amount } into pggroup
                                    select new { accounting_period = pggroup.Key.ACCOUNTING_PERIOD, amount = pggroup.Sum(x => x.Amount) };

                    foreach (var mon in MonthList)
                    {
                        int accounting_period = int.Parse(mon.accounting_period) - 1;
                        PGContent[accounting_period] = (float)mon.amount/1000000;
                    }


                    MonthRow[item.PG] = PGContent;

                    }





                return Json(MonthRow, JsonRequestBehavior.AllowGet);

            }


            return View();
        }

This code worked great for me since I am pulling from a Linq to SQL query instead of adding data directly into the code. My problems stemmed from mainly putting the data pulls outside of the foreach loops so it only pulled 1 piece of data from the SQL instead of all twelve months. I hope this helps some one else who is trying to pull data in from SQL data sources into multidimensional arrays.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.