score:1

Accepted answer

Something like this :

        var p1 = new Product(){Count=15, Name="A", Vendor = 1, Year = 1990};
        var p2 = new Product() { Count = 20, Name = "A", Vendor = 2, Year = 1990 };
        var p3 = new Product() { Count = 5, Name = "A", Vendor = 4, Year = 1998 };
        var p4 = new Product() { Count = 15, Name = "B", Vendor = 1, Year = 1995 };
        var p5 = new Product() { Count = 2, Name = "B", Vendor = 1, Year = 1995 };

        var inputList = new[] {p1, p2, p3, p4, p5};

        var newStructure = inputList
            .GroupBy( p => new { p.Name, p.Year } )
            .Select( g => new { g.Key.Name, g.Key.Year, VendorCount = g.ToDictionary(p => p.Vendor, p => p.Count) }
          );

Although I don't think you can use Vendor as a dictionary key, because they are not unique as it stands

score:2

Use this if the combination of (Name, Year, Vendor) is unique:

inputList.GroupBy(x => new { x.Name, x.Year })
         .Select(x => new
                      {
                          ProductName = x.Key.Name,
                          OriginYear = x.Key.Year, 
                          Vendor_Count = x.ToDictionary(y => y.Vendor
                                                        y => y.Count)
                      })
         .OrderBy(x => x.ProductName).ThenBy(x => x.OriginYear);

Use this if it isn't unique:

inputList.GroupBy(x => new { x.Name, x.Year })
         .Select(x => new
                      {
                          ProductName = x.Key.Name,
                          OriginYear = x.Key.Year, 
                          Vendor_Count = x.GroupBy(y => y.Vendor)
                                          .ToDictionary(y => y.Key,
                                                        y => y.Sum(z => z.Count))
                      })
         .OrderBy(x => x.ProductName).ThenBy(x => x.OriginYear);

Related Articles