CSnacker CSnacker - 2 months ago 11
C# Question

Transform List into 2D Array

I have a List of data with this form:

group date count
L1 2016-09-13 1
L2 2016-09-13 2
L3 2016-09-13 3
L1 2016-09-12 1
L2 2016-09-12 2
L3 2016-09-12 3
... ... ...


And I want a 2D Array, it should be all strings, lets ignore the variable list size. The Array should look like this:

group 2016-09-13 2016-09-12
L1 1 1
L2 2 2
L3 3 3


I tried it this way, I am kinda stuck.

public class ChartTmp
{
public string date, group, count;
}
List<ChartTmp> list = new List<ChartTmp>();
//... fill list with data
string [,] data = new string[15, 15];

data[0, 0] = "group";
for (int i = 0; i<15;i++ ){
curr_date = list[i].date;
if (last_date != curr_date) {
data[0, counter] = curr_date;
last_date = curr_date;
counter++;
}
data[0, counter] = list[i].group;
data[i, counter] = list[i].count;
}

Answer

You can use nested Dictionaries, so it will take care of aggregating data easily without much code, like so

    static void Main(string[] args)
    {
        var data = new[]{
            new { group="L1", date="2016-09-13", count=1},
            new { group="L2", date="2016-09-13", count=2},
            new { group="L3", date="2016-09-13", count=3},
            new { group="L1", date="2016-09-12", count=1},
            new { group="L2", date="2016-09-12", count=2},
            new { group="L3", date="2016-09-12", count=3}
        };

        //convert data to dictionaries
        var dictionaries = new Dictionary<string, Dictionary<string, int>>();
        foreach (var row in data)
        {
            if (!dictionaries.ContainsKey(row.group))
                dictionaries[row.group] = new Dictionary<string, int>();
            if (!dictionaries[row.group].ContainsKey(row.date))
                dictionaries[row.group][row.date] = row.count;
        }

I think it's already very easy to use and display, you can get the count using dictionaries["L1"]["2016-09-13"] for example, if you still want 2D array, convert the dictionary of dictionaries to 2D array using some for loops

        //convert dictionary of dictionaries to 2D array
        int groupNum = dictionaries.Keys.Count, dateNum = dictionaries.First().Value.Keys.Count;
        string[,] array = new string[groupNum + 1, dateNum + 1];
        array[0, 0] = "group";

        //assign dates
        for (int i = 1; i <= dateNum; i++)
            array[0, i] = dictionaries.First().Value.Keys.ElementAt(i - 1);

        //assign groups
        for (int i = 1; i <= groupNum; i++)
            array[i, 0] = dictionaries.Keys.ElementAt(i - 1);

        //assign counts
        for (int group = 1; group <= groupNum; group++)
            for (int date = 1; date <= dateNum; date++)
            {
                array[group, date] = "0";
                string groupName = array[group,0], dateString = array[0,date];
                if(dictionaries[groupName].ContainsKey(dateString))
                    array[group, date] = dictionaries[groupName][dateString].ToString();
            }

        //print the 2D array
        for (int row = 0; row < groupNum + 1; row++)
        {
            for (int column = 0; column < dateNum + 1; column++)
                Console.Write("{0} ", array[row, column]);
            Console.WriteLine();
        }

        Console.ReadLine();
    }
Comments