public void GroupBy(string groupColumnNames, string aggregateColumnNames = null) { // TODO: Сворачиваем за N^2. Переделать на N*log(N) List <ValueTableColumn> GroupColumns = GetProcessingColumnList(groupColumnNames, true); List <ValueTableColumn> AggregateColumns = GetProcessingColumnList(aggregateColumnNames, true); List <ValueTableRow> new_rows = new List <ValueTableRow>(); foreach (ValueTableRow row in _rows) { StructureImpl search = new StructureImpl(); foreach (ValueTableColumn Column in GroupColumns) { search.Insert(Column.Name, row.Get(Column)); } ValueTableRow new_row = null; foreach (ValueTableRow nrow in new_rows) { if (CheckFilterCriteria(nrow, search)) { new_row = nrow; break; } } if (new_row == null) { new_row = new ValueTableRow(this); foreach (ValueTableColumn Column in GroupColumns) { new_row.Set(Column, row.Get(Column)); } new_rows.Add(new_row); } foreach (ValueTableColumn Column in AggregateColumns) { IValue old = new_row.Get(Column); decimal d_old; if (old.DataType != Machine.DataType.Number) { d_old = 0; } else { d_old = old.AsNumber(); } IValue current = row.Get(Column); decimal d_current; if (current.DataType != Machine.DataType.Number) { d_current = 0; } else { d_current = current.AsNumber(); } new_row.Set(Column, ValueFactory.Create(d_old + d_current)); } } _rows.Clear(); _rows.AddRange(new_rows); { int i = 0; while (i < _columns.Count()) { ValueTableColumn Column = _columns.FindColumnByIndex(i); if (GroupColumns.IndexOf(Column) == -1 && AggregateColumns.IndexOf(Column) == -1) { _columns.Delete(Column); } else { ++i; } } } }
public void GroupBy(string groupColumnNames, string aggregateColumnNames = null) { List <ValueTableColumn> GroupColumns = GetProcessingColumnList(groupColumnNames, true); List <ValueTableColumn> AggregateColumns = GetProcessingColumnList(aggregateColumnNames, true); foreach (ValueTableColumn group_column in GroupColumns) { if (AggregateColumns.Find(x => x.Name == group_column.Name) != null) { throw ColumnsMixedException(group_column.Name); } } var uniqueRows = new Dictionary <ValueTableRow, ValueTableRow>(new RowsByColumnsEqComparer(GroupColumns)); int new_idx = 0; foreach (ValueTableRow row in _rows) { if (uniqueRows.ContainsKey(row)) { ValueTableRow old_row = uniqueRows[row]; foreach (var Column in AggregateColumns) { IValue current = row.Get(Column); if (current.DataType == DataType.Number) { decimal sum = old_row.Get(Column).AsNumber() + current.AsNumber(); old_row.Set(Column, ValueFactory.Create(sum)); } } } else { ValueTableRow new_row = _rows[new_idx++]; foreach (var Column in GroupColumns) { new_row.Set(Column, row.Get(Column)); } foreach (var Column in AggregateColumns) { if (row.Get(Column).DataType != DataType.Number) { new_row.Set(Column, ValueFactory.Create(0)); } else { new_row.Set(Column, row.Get(Column)); } } uniqueRows.Add(new_row, new_row); } } _rows.RemoveRange(new_idx, _rows.Count() - new_idx); int i = 0; while (i < _columns.Count()) { ValueTableColumn Column = _columns.FindColumnByIndex(i); if (GroupColumns.IndexOf(Column) == -1 && AggregateColumns.IndexOf(Column) == -1) { _columns.Delete(Column); } else { ++i; } } }