patterncsharpMinor
Group collections by their elements property
Viewed 0 times
elementsgrouppropertycollectionstheir
Problem
I have a
And three transactions classes that have a reference to
I have a collection for each of transaction type. And I want to get this collection to be "grouped" by their elements
Right now I am doing so by this function:
```
private IEnumerable _GetCustomerInfo(
IEnumerable payments, IEnumerable invoices,
IEnumerable orders)
{
var invoicesGroupdByCustomers = invoices.GroupBy(x => x.CustomerId);
var ordersGroupdByCustomers = orders.GroupBy(x => x.CustomerId);
var paymentsGroupdByCustomers = payments.GroupBy(x => x.CustomerId);
var result = new List();
foreach (var group in invoicesGroupdByCustomers)
result.Add(new CustomerInfo(group.Key,
ordersGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
group,
paymentsGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key)));
foreach (var group in ordersGroupdByCustomers)
if (!result.Any(x => x.CustomerId == group.Key))
result.Add(new CustomerInfo(group.Key,
group,
invoicesGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
Customer class:public class Customer
{
public Guid Id { get; set; }
// Some other properties...}And three transactions classes that have a reference to
Customer: public class Order
{
public Guid CustomerId { get; set; }
// Some other properties...}
public class Invoice
{
public Guid CustomerId { get; set; }
// Some other properties...}
public class Payment
{
public Guid CustomerId { get; set; }
// Some other properties...}I have a collection for each of transaction type. And I want to get this collection to be "grouped" by their elements
CustomerId properties. So, as a result I'd like to get a collection of such objects:public class CustomerInfo
{
public CustomerInfo(Guid customerId, IEnumerable orders,
IEnumerable invoices, IEnumerable payments){...}
public Guid CustomerId { get; set; }
public IEnumerable Invoices { get; set; }
public IEnumerable Orders { get; set; }
public IEnumerable Payments { get; set; }
}Right now I am doing so by this function:
```
private IEnumerable _GetCustomerInfo(
IEnumerable payments, IEnumerable invoices,
IEnumerable orders)
{
var invoicesGroupdByCustomers = invoices.GroupBy(x => x.CustomerId);
var ordersGroupdByCustomers = orders.GroupBy(x => x.CustomerId);
var paymentsGroupdByCustomers = payments.GroupBy(x => x.CustomerId);
var result = new List();
foreach (var group in invoicesGroupdByCustomers)
result.Add(new CustomerInfo(group.Key,
ordersGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
group,
paymentsGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key)));
foreach (var group in ordersGroupdByCustomers)
if (!result.Any(x => x.CustomerId == group.Key))
result.Add(new CustomerInfo(group.Key,
group,
invoicesGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
Solution
If they all implemented a common interface then you could simplify it.
Concat the the items together
Then project them into your class
public interface ICustomerItem
{
Guid CustomerId {get;}
}Concat the the items together
var items = invoices.Concat(payments).Concat(orders);Then project them into your class
items
.GroupBy(x => x.CustomerId)
.Select(g =>
new CustomerInfo(g.Key,
g.OfType(),
g.OfType(),
g.OfType())Code Snippets
public interface ICustomerItem
{
Guid CustomerId {get;}
}var items = invoices.Concat(payments).Concat(orders);items
.GroupBy(x => x.CustomerId)
.Select(g =>
new CustomerInfo(g.Key,
g.OfType<Order>(),
g.OfType<Payment>(),
g.OfType<Invoice>())Context
StackExchange Code Review Q#18657, answer score: 6
Revisions (0)
No revisions yet.