- The grouping operators assist with grouping elements of a sequence together by a common key.
- GroupBy operator return a sequence of IGrouping<K, T> elements.
- Where K - is key of field type which is used for grouping
- Where T - is actual object
GroupBy- Type 1 - with default comparer- Example
class Customer
{
public int CustomerID { get; set; }
public string CustomerType { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Customer> Customers = new List<Customer> {
new Customer(){ CustomerID=1, Name="XYZ Private Limited", CustomerType="WholeSale" },
new Customer(){ CustomerID=2, Name="ABC Private Limited", CustomerType="WholeSale" },
new Customer(){ CustomerID=3, Name="MS Infotech", CustomerType="Retail" },
new Customer(){ CustomerID=4, Name="Oracle" , CustomerType="WholeSale" },
new Customer(){ CustomerID=5, Name="IBM Hardware Limited", CustomerType="Retail" },
};
IEnumerable<IGrouping<string, Customer>> CustomersGroup = Customers.GroupBy(x => x.CustomerType);
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
}
}
//Output
Group Name:WholeSale
Customers
-------------
ID:1, Name:XYZ Private Limited
ID:2, Name:ABC Private Limited
ID:4, Name:Oracle
Group Name:Retail
Customers
-------------
ID:3, Name:MS Infotech
ID:5, Name:IBM Hardware Limited
{
public int CustomerID { get; set; }
public string CustomerType { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Customer> Customers = new List<Customer> {
new Customer(){ CustomerID=1, Name="XYZ Private Limited", CustomerType="WholeSale" },
new Customer(){ CustomerID=2, Name="ABC Private Limited", CustomerType="WholeSale" },
new Customer(){ CustomerID=3, Name="MS Infotech", CustomerType="Retail" },
new Customer(){ CustomerID=4, Name="Oracle" , CustomerType="WholeSale" },
new Customer(){ CustomerID=5, Name="IBM Hardware Limited", CustomerType="Retail" },
};
IEnumerable<IGrouping<string, Customer>> CustomersGroup = Customers.GroupBy(x => x.CustomerType);
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
}
}
//Output
Group Name:WholeSale
Customers
-------------
ID:1, Name:XYZ Private Limited
ID:2, Name:ABC Private Limited
ID:4, Name:Oracle
Group Name:Retail
Customers
-------------
ID:3, Name:MS Infotech
ID:5, Name:IBM Hardware Limited
- As you can see from the above example GroupBy returns IGrouping<string, Customer>,in this key of type string because Customer.CustomerType is of type string and the as source type is of type Customer
- It is not compulsory to put return type as IEnumerable<IGrouping<string, Customer>>, it can be declared as var or can be return as a List, just for understanding I have used IEnumerable<IGrouping<string, Customer>>
List<IGrouping<string, Customer>> CustomersGroup = Customers.GroupBy(x => x.CustomerType).ToList();
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
- Both(above/below) versions will return the same result as first Example
var CustomersGroup = Customers.GroupBy(x => x.CustomerType)
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
GroupBy- Type 2 - with Custom comparer- Example
- IEqualityComparer<T> Interface allows the implementation of customized equality comparison for collections
- That is, you can create your own definition of equality for type
T
, and specify that this definition be used with a collection type that accepts the IEqualityComparer<T> generic interface. - Before we look into GroupBy - Type 2, we will discuss about IEqualityComparer interface and how it works
class CustomerEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
if (this.GetHashCode(x) == this.GetHashCode(y))
return true;
else
return false;
}
public int GetHashCode(string obj)
{
return obj.Length; // Just any logic to generate hashcode
}
}
{
public bool Equals(string x, string y)
{
if (this.GetHashCode(x) == this.GetHashCode(y))
return true;
else
return false;
}
public int GetHashCode(string obj)
{
return obj.Length; // Just any logic to generate hashcode
}
}
- As you can see from above code the IEqualityComparer contains two methods GetHashCode and Equals
- GetHashCode- method is just a helper method, as IEqualityComparer<T> generic interface, we are passing string type here as CustomerType is of type string.
- It is upto us to decide how the hashcode will be generator,
- Even without calling this method also we can
- Equals - method is the actual method for checking the equality, it is up to us to decide whether we are going to use the GetHashCode or not, for checking the equality.
- Just for to show how it works I have implemented a dummy logic.
GroupBy- Type 2 - with Custom Equality comparer- Example
IEnumerable<IGrouping<string, Customer>> CustomersGroup = Customers.GroupBy(x => x.CustomerType, new CustomerEqualityComparer());
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
- Any way the result will be the same as the first type, as we didn't do any big change in the Custom Comparer class logic
GroupBy- Type 3 - Example
- This type is same as the first Type, with the small change the return type of the GroupBy operator
- In the Type 1 Example, we just specify the group by column, so the return type is the base type of the sequence i.e Customer by default
- We have a option to specify the return data/type of the object as custom
- In this example i am going to change the first type slightly and show to how to specify the custom return type.
IEnumerable<IGrouping<string, Customer>> CustomersGroup = Customers.GroupBy(x => x.CustomerType, y => y);
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(Customer C in item)
{
Console.WriteLine($"ID:{C.CustomerID}, Name:{C.Name}");
}
Console.WriteLine();
}
Console.ReadLine();
IEnumerable<IGrouping<string, string>> CustomersGroup = Customers.GroupBy(x => x.CustomerType, y => y.Name);
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(string CustomerName in item)
{
Console.WriteLine($"Name:{CustomerName}");
}
Console.WriteLine();
}
Console.ReadLine();
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(string CustomerName in item)
{
Console.WriteLine($"Name:{CustomerName}");
}
Console.WriteLine();
}
Console.ReadLine();
GroupBy- Type 4 - Example
- Type 4 is nothing but a combination of both Type 2 and Type 3
IEnumerable<IGrouping<string, string>> CustomersGroup = Customers.GroupBy(x => x.CustomerType, y => y.Name, new CustomerEqualityComparer());
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(string CustomerName in item)
{
Console.WriteLine($"Name:{CustomerName}");
}
Console.WriteLine();
}
Console.ReadLine();
foreach (var item in CustomersGroup)
{
Console.WriteLine($"Group Name:{item.Key}\n");
Console.WriteLine("Customers");
Console.WriteLine("-------------");
foreach(string CustomerName in item)
{
Console.WriteLine($"Name:{CustomerName}");
}
Console.WriteLine();
}
Console.ReadLine();
No comments:
Post a Comment