2015-07-23 12 views
2

У меня есть список родовых C# List<Result> результатов которых имеют несколько полей с несколькими рядами данных в нем, как следует из типа RESULTОбъединение нескольких строк столбца в списке C# на основе других столбцов

public class Result 
{ 
    public int TrdID; 
    public string Term; 
    public double Price; 
    public string Seller; 
    public string Buyer; 
    public bigint Quantity; 
} 

и тому данные следующим образом

TrdID Term  Price Seller Buyer Quantity 
1000  201508  1  ABC XYZ 10 
1010  201508  2  ACB PQR 10 
1002  201507  1.5 ABX PEW 20 
1002  201506  1.5 ABX PEW 20 
1002  201508  1.5 ABX PEW 20 

Теперь я хочу, чтобы обрабатывать вышеуказанные данные и возвращает один для одного уникального ID, предусмотренного конкретных ID всех столбцов будет такими же, за исключением Term. Например, у меня есть три записи для ID 1002, я хочу, чтобы объединить их в одной записи, преобразовав срок до DateTime и введение двух новых столбцов, говоря startDate и EndDate и ожидаемые результаты следующие

Ожидаемый результат

TrdID  StartDate  EndDate  Price Seller Buyer Quantity 
    1000  08/01/2015 08/31/2015 1  ABC XYZ 10 
    1010  08/01/2015 08/31/2015 2  ACB PQR 10 
    1002  06/01/2015 08/31/2015 1.5 ABX PEW 60 

из приведенных выше данных, можно увидеть, что у меня есть два новых столбца с именем StartDate и EndDate вместо Term столбца, который используется для получения значений для обоих StartDate и EndDate. Кроме того, есть изменения в Quantity в последней строке, которая является суммой всех величин для конкретного ID, т.е., No.Of times ID repeated*Quantity

Вот, у меня есть два случая, чтобы решить

case1:. Если это всего лишь одна запись для определенного ID, скажем, 1000, тогда StartDate будет первым днем ​​месяца в столбце «Срок», а EndDate будет последним днем ​​месяца в Term т.е. 08/01/2015 and 08/31/2015. Никаких изменений Quantity

Вариант 2:. Если имеется несколько записей для конкретного ID сказать 1002 (все условия будут в последовательности), то StartDate будет первый день наименьшего месяца, т.е., 06/01/2015 и EndDate будет быть последним днем ​​наибольшего месяца столбца «Срок», т. е., 08/31/2015. Quantity=No.Of times ID repeated*Quantity т., 20*3=60

Мой результате список будет типа

public class ProcessedResult 
{ 
    public int TrdID; 
    public DateTime StartDate; 
    public DateTime EndDate; 
    public double Price; 
    public string Seller; 
    public string Buyer; 
    public bigint Quantity; 
} 

Могу ли я знаю хороший способ решить эту проблему?

+2

Что вы пробовали? Где вы застряли? 'GroupBy',' Min' и 'Max' кажутся разумными функциями. –

+1

Если есть несколько записей с одним и тем же TrdID, будут ли значения цены, продавца, покупателя и количества одинаковыми для всех записей? –

+0

Да, они такие же – DoIt

ответ

2

При условии, что продавец и покупатель будет такой же, как в примере, вы представили в своем сообщении, что вам нужно что-то вроде этого:

var result = list.GroupBy(result => result.TrdID) 
       .Select(gr => { 
       var startDate = DateTime.ParseExact(gr.OrderBy(x => x.Term).First().Term, "yyyyMM", CultureInfo.InvariantCulture); 
       var endDate = DateTime.ParseExact(gr.OrderByDescending(x => x.Term).First().Term, "yyyyMM", CultureInfo.InvariantCulture);      
       return new ProcessedResult 
       { 
        TrdID = gr.Key 
        StartDate = new DateTime(startDate.Year, startDate.Month, 1), 
        EndDate = (new DateTime(endDate.Year, endDate.Month, 1)).AddMonth(1).AddDays(-1), 
        Price = gr.First().Price, 
        Seller = gr.First().Seller, 
        Buyer = gr.First().Buyer, 
        Quantity = gr.Sum(x=>x.Quantity) 
       } 
      }); 

По сути, мы делаем группу, из результаты (список содержит ваши результаты). Фокус в том, как мы строим StartDate и EndDate. Там мы делаем порядок строк в той же группе, и мы получаем первый, чтобы получить строковое представление StartDate. Затем мы используем метод DateTime.ParseExact, потому что мы знаем точный формат DateTime.Что касается EndDate, мы делаем OrderByDescending, чтобы получить последнюю дату - мы можем сделать OrderBy и получить последний элемент, это эквивалентно. Затем мы снова применим DateTime.ParseExact.

+0

Корректор: 'Необработанное исключение типа 'System.FormatException' произошло в mscorlib.dll Дополнительная информация: String не была признана действительной DateTime.' Это потому, что 'Term' является строкой в моем списке – DoIt

+0

И я не думаю, что это дает мне StartDate как первый день этого месяца, а EndDate - последний день месяца, который находится в поле строки строки – DoIt

+0

. Я внес незначительное изменение в ваш ответ, чтобы удалить исключение в первом комментарий от 'DateTime.ParseExact (gr.OrderBy (x => x.Term) .First(). Term', но это все еще не дает мне правильный EndDate как' 08/31/2015', вместо этого он дает '08/01/2015' – DoIt

 Смежные вопросы

  • Нет связанных вопросов^_^