c#Linq查询按组分组,然后分组

时间:2015-02-13 03:10:46

标签: c# linq sorting group-by subquery

问题:我有一个项目列表,我需要首先分组,然后按产品组中的项目数分组。代码如下。目标是创建匹配组,其中区域和每个匹配中可用的产品。区域和产品可能会发生变化,但应始终对可用的产品数量进行分组。

例如,

。鉴于以下......

结果应该是......

Group 1
Zone = "EAST", Product = "Bananas", ShippingTime = "3_Days" };
Zone = "EAST", Product = "Oranges", ShippingTime = "5_Days" };
Zone = "SOUTH", Product = "Bananas", ShippingTime = "3_Days" };
Zone = "SOUTH", Product = "Oranges", ShippingTime = "10_Days" };

第2组

Zone = "WEST", Product = "Oranges", ShippingTime = "3_Days" };
Zone = "WEST", Product = "Oranges", ShippingTime = "5_Days" };
Zone = "WEST", Product = "Oranges", ShippingTime = "10_Days" };
Zone = "WEST", Product = "Apples", ShippingTime = "3_Days" };
Zone = "WEST", Product = "Apples", ShippingTime = "5_Days" };
Zone = "WEST", Product = "Apples", ShippingTime = "5_Days" };
Zone = "WEST", Product = "Bananas", ShippingTime = "3_Days" };
Zone = "WEST", Product = "Bananas", ShippingTime = "5_Days" };
Zone = "WEST", Product = "Bananas", ShippingTime = "5_Days" };

理想的分组是从第2组中突破以下(因为它们与第1组中的匹配)并添加到 第1组,因此留下第2组中的残差。

Zone = "WEST", Product = "Bananas", ShippingTime = "3_Days" };
Zone = "WEST", Product = "Oranges", ShippingTime = "10_Days" };

这是我一直在使用的测试。我用linq做的一切似乎都没有完成任务。 在此先感谢您的想法。

public void should_group_products_and_shippingtimes()
        {
            {
                Bananas = "Limited DR";
                var a = new MyClass { Id = 1, Zone = "EAST", Product = "Bananas", ShippingTime = "3_Days" };
                var b = new MyClass { Id = 2, Zone = "EAST", Product = "Oranges", ShippingTime = "5_Days" };
                var c = new MyClass { Id = 3, Zone = "SOUTH", Product = "Bananas", ShippingTime = "3_Days" };
                var d = new MyClass { Id = 4, Zone = "SOUTH", Product = "Oranges", ShippingTime = "10_Days" };
                var e = new MyClass { Id = 5, Zone = "WEST", Product = "Oranges", ShippingTime = "3_Days" };
                var f = new MyClass { Id = 6, Zone = "WEST", Product = "Oranges", ShippingTime = "5_Days" };
                var g = new MyClass { Id = 7, Zone = "WEST", Product = "Oranges", ShippingTime = "10_Days" };
                var h = new MyClass { Id = 8, Zone = "WEST", Product = "Apples", ShippingTime = "3_Days" };
                var i = new MyClass { Id = 9, Zone = "WEST", Product = "Apples", ShippingTime = "5_Days" };
                var j = new MyClass { Id = 10, Zone = "WEST", Product = "Apples", ShippingTime = "5_Days" };
                var k = new MyClass { Id = 11, Zone = "WEST", Product = "Bananas", ShippingTime = "3_Days" };
                var l = new MyClass { Id = 12, Zone = "WEST", Product = "Bananas", ShippingTime = "5_Days" };
                var m = new MyClass { Id = 13, Zone = "WEST", Product = "Bananas", ShippingTime = "5_Days" };
                var myList = new List<MyClass>();
                myList.AddRange(new[] {a,b,c,d,e,f,g,h,i,j,k,l,m});

                var sublist = (from ee in myList
                                                from ff in myList
                                                where ee.Product == ff.Product
                                                      && ee.Id != ff.Id
                                                select ee).Distinct();

                var match1 =
                       myList.AsEnumerable().GroupBy(
                           record =>
                           new { PRODUCT = record.Product, SHIPPINGTIME = record.ShippingTime }).Where(z => z.Count() == 1);

                var match2 =
                       myList.AsEnumerable().GroupBy(
                           record =>
                           new { PRODUCT = record.Product, SHIPPINGTIME = record.ShippingTime }).Where(z => z.Count() == 2);

                var match3 =
                       myList.AsEnumerable().GroupBy(
                           record =>
                           new { PRODUCT = record.Product, SHIPPINGTIME = record.ShippingTime }).Where(z => z.Count() == 3);

                var match4 =
                       myList.AsEnumerable().GroupBy(
                           record =>
                           new { PRODUCT = record.Product, SHIPPINGTIME = record.ShippingTime }).Where(z => z.Count() == 4);

                var match5 =
                       myList.AsEnumerable().GroupBy(
                           record =>
                           new { PRODUCT = record.Product, SHIPPINGTIME = record.ShippingTime }).Where(z => z.Count() == 5);

                // Get the total from each of these group where they match, throw the rest out.


                foreach (var entry in sublist)
                {
                    Console.WriteLine(entry);

                }

                Assert.That(sublist, Is.Not.Null);
            }
        } 

//支持班级

public class MyClass
    {
        public int Id { get; set; }
        public string Zone { get; set; }
        public string Product { get; set; }
        public string ShippingTime { get; set; }
    }

1 个答案:

答案 0 :(得分:1)

我不确定我是否理解你,但我认为你想做那样的事情:

myList.Select(record => record.Product)
      .Distinct()
      .Select(p => new 
              { 
                  Product = p, 
                  Zones = myList.Where(r => r.Product == p)
                                .Select(r => r.Zone)
                                .Distinct() 
              })
      .GroupBy(an => an.Zones.Count())

enter image description here