I have input data given as a list of objects:
Name: "Room A",
Time: "15:00",
Topic: "Some Topic"
Name: "Room A",
Time: "18:00",
Topic: "Some Other Topic"
Name: "Room B",
Time: "12:00",
Topic: "Some More Topic"
Name: "Room C",
Time: "13:00",
Topic: "Even More Topic"
and I have to create different tables from that. For a start, there should be a table where rows are based on time, and cols are based on the Name, but in the future, when the objects grow, I would like to be able to pivot around other properties.
I would like to code something like the following:
var structure = new SomeCSharpStructure(); // <------
for(int i=0;i<24) structure.AddRow(i+":00");
foreach(var name in inputData.Select(x=>x.Name).Distinct()) structure.AddColumn(name);
foreach(var data in inputData) {
structure[data.Name][data.Time] = data.Topic; // or
// structure.AddCell(data.Name,data.Time,data.Topic);
}
...
foreach(var row in structure.getRows()) foreach(var cell in row.getCell())
{
PrintCellContent(cell);
}
although I am also open for other suggestions.
But right now I am searching for a structure that would support such an instantiation without spilling NullPointerExceptions
or IndexOutOfRangeExceptions
all over the place. Before I implement it myself, I'd like to make sure there is none available.
Does anyone know a structure that would suit my needs?
Instead of writing custom code that groups your data, you can use NReco.PivotData library that already implements pivot table calculations (I'm the author of this library, and it can be used for free). It provides PivotTable structure for accessing table values in terms of rows and columns:
var pvtData = new PivotData(new[] {"Name", "Time"}, new CountAggregatorFactory() );
pvtData.ProcessData( inputData, new ObjectMember().GetValue );
var pvtTbl = new PivotTable(new[] {"Name"}, new[] {"Time"}, pvtData);
var columns = pvtTbl.ColumnKeys;
var rows = pvtTbl.RowKeys;
var cellValue = pvtTbl[0,0].Value; // get first cell value
Some explanations: