Linq groupby的两个属性

本文关键字:两个 属性 groupby Linq | 更新日期: 2023-09-27 17:50:34

假设我有一个订单列表。每个订单都有对客户和他们购买的产品的引用。像这样:

class Orders 
{
    public int CustomerId {get;set;}
    public int ProductId {get;set;}
}

我想将不同客户拥有相同产品集的所有订单分组在同一组中。

  • 客户1 -产品1&2
  • 客户2 -产品1&2&3
  • 客户3 -产品1&2
  • 客户4 -产品3&4&5

在本例中,客户1&3的订单将在同一组中,客户2&4的订单将有自己的组。

这可以用LINQ实现吗?我开始尝试通过CustomerId分组,但我在如何从那里继续迷路。

Linq groupby的两个属性

Having:

List<Orders> orders = new List<Orders>();
orders.Add(new Orders { CustomerId = 1, ProductId = 1 });
orders.Add(new Orders { CustomerId = 1, ProductId = 2 });
orders.Add(new Orders { CustomerId = 2, ProductId = 2 });
orders.Add(new Orders { CustomerId = 2, ProductId = 3 });
orders.Add(new Orders { CustomerId = 3, ProductId = 1 });
orders.Add(new Orders { CustomerId = 3, ProductId = 2 });
orders.Add(new Orders { CustomerId = 4, ProductId = 3 });
orders.Add(new Orders { CustomerId = 4, ProductId = 4 });

LINQ查询:

 var groupedCustomers = 
         orders.GroupBy(i => i.CustomerId)
               .Select(i => new { CUSTOMER = i.Key, 
                                  ORDERS = i.Select(j => j.ProductId)
                                            .OrderBy(j => j)
                                          //.Distinct() to ignore duplicate orders
                                            .ToArray() })
               .ToList();
 var result = groupedCustomers.GroupBy(i => i.ORDERS, new IntArrayComparer()).ToList();

这是比较器

 public class IntArrayComparer : IEqualityComparer<int[]>
 {    
     public bool Equals(int[] x, int[] y)
     {
         return x.SequenceEqual(y);
     }
     public int GetHashCode(int[] obj)
     {
         return base.GetHashCode();
     }
 }

EDIT:如果您正在寻找更智能的GetHashCode功能,您可以尝试这样做:

public int GetHashCode(int[] obj)
{
    return string.Join(",", obj.Select(i => i.ToString())).GetHashCode();
}