В счете-фактуре показать строку/целый массив уникальных продуктов

У меня есть список счетов-фактур и всех продуктов в каждом счете-фактуре. Каждый счет-фактура может иметь несколько одинаковых продуктов.

class InvoiceProducts 
{
    public int InvoiceID { get; set; }
    public int ProductID { get; set; }
}


var list = new List<InvoiceProducts>();
list.Add(new { InvoiceID = 7000, ProductID=15});
list.Add(new { InvoiceID = 7000, ProductID=10});
list.Add(new { InvoiceID = 7000, ProductID=10});
list.Add(new { InvoiceID = 7000, ProductID=15});

list.Add(new { InvoiceID = 7010, ProductID=12});
list.Add(new { InvoiceID = 7010, ProductID=20});
list.Add(new { InvoiceID = 7010, ProductID=12});

list.Add(new { InvoiceID = 7021, ProductID=1});
list.Add(new { InvoiceID = 7021, ProductID=1});

Могу ли я попросить помощи в группировке по InvoiceID и иметь (отсортированный) целочисленный список уникальных продуктов для каждого счета (причина сортировки в том, что мне нужно позже сопоставить это с другими счетами с теми же продуктами)

i.e.

InvoiceID   ProductID
7000        10,15       
7010        12,20
7021        1

Неудачные попытки:

  var tl2 = List
      .GroupBy(x => x.InvoiceID)
      .ToDictionary(y => y.Key, y => y.Distinct().ToList());

Объяснение неудачной попытки: у него есть словарь, который правильно сгруппирован по InvoiceID, но в счете 7000 было 4 позиции вместо 2 уникальных продуктов.


person Peter PitLock    schedule 29.09.2015    source источник


Ответы (1)


Вам нужен ToLookup здесь — он разработан именно для этого сценария .

var lookup = list.ToLookup(x => x.InvoiceID, x => x.ProductID);

Он по-прежнему будет содержать повторяющиеся идентификаторы продуктов, но вы можете легко сделать их разными при получении:

var products = list[7000].Distinct();

Или вы можете просто использовать Distinct() в своем списке:

var lookup = list.Distinct()
                 .ToLookup(x => x.InvoiceID, x => x.ProductID);

Это будет работать с кодом, использующим анонимный тип, но нет, если вы действительно используете свой тип InvoiceProducts. Вы всегда можете спроецировать:

var lookup = list.Select(x => new { x.InvoiceID, x.ProductID })
                 .Distinct()
                 .ToLookup(x => x.InvoiceID, x => x.ProductID);

... или просто сделайте так, чтобы ваш тип InvoiceProducts реализовал равенство соответствующим образом.

person Jon Skeet    schedule 29.09.2015