Сведение входных данных — есть ли структура, которую я могу использовать?

У меня есть входные данные в виде списка объектов:

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"

и я должен создать из этого разные таблицы. Для начала должна быть таблица, в которой строки основаны на времени, а столбцы — на имени, но в будущем, когда объекты будут расти, я хотел бы иметь возможность вращаться вокруг других свойств.

Я хотел бы закодировать что-то вроде следующего:

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);
}

хотя я также открыт для других предложений.

Но прямо сейчас я ищу структуру, которая поддерживала бы такое создание, не разбрасывая NullPointerExceptions или IndexOutOfRangeExceptions повсюду. Прежде чем я реализую его сам, я хотел бы убедиться, что его нет в наличии.

Кто-нибудь знает структуру, которая удовлетворит мои потребности?


person Alexander    schedule 13.07.2016    source источник


Ответы (1)


Вместо написания пользовательского кода, который группирует ваши данные, вы можете использовать библиотеку NReco.PivotData, которая уже реализует расчеты сводной таблицы (я являюсь автором этой библиотеки, и ею можно пользоваться бесплатно). Он предоставляет структуру сводной таблицы для доступа к значениям таблицы с точки зрения строк и столбцов:

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

Некоторые пояснения:

  • Класс PivotData создает куб в памяти (многомерный набор данных) и выполняет агрегацию данных.
  • ObjectMember предоставляет средство доступа к свойствам модели POCO для значений измерений.
  • Класс PivotTable предоставляет табличную модель, которую можно использовать для визуализации сводной таблицы. Его можно использовать для получения итогов и промежуточных итогов.
person Vitaliy Fedorchenko    schedule 16.08.2016
comment
Слишком поздно для меня, но, надеюсь, это поможет другим пользователям. :-) - person Alexander; 16.08.2016
comment
@Alexander Александр, теперь ты знаешь о PivotData в следующий раз :-) - person Vitaliy Fedorchenko; 16.08.2016
comment
@VitaliyFedorchenko: как вы думаете, ваша библиотека может решить мою проблему: stackoverflow.com/questions/43991726/ Я извлекаю данные из куба и добавляю данные в список‹Список‹ нить>>. Любое предложение помощи приветствуется - person OpenStack; 16.05.2017
comment
@OpenStack да, вы можете использовать PivotData для поворота ваших данных. Я предоставил ответ с образцом кода в вашем вопросе. - person Vitaliy Fedorchenko; 17.05.2017