Reputation: 383
i have 2 generic lists of the same type "Person"
each list have List of "Order" property.
Person ID (identifier) can repeat in booth lists. but orders can not.
my desired output should be 1 list, when each person have one instance
and all the orders are merged.
my question is, what is the best way (performance) to do that ?
as explained in the next code:
class Program
{
public class Order
{
public string OrderId { get; set; }
}
public class Person
{
public string Id { get; set; }
public List<Order> orders { get; set; }
}
static void Main(string[] args)
{
// build list 1
Person p1 = new Person() { Id = "John", orders = new List<Order>() };
p1.orders.Add(new Order() { OrderId = "John order 1" });
Person p2 = new Person() { Id = "Paul", orders = new List<Order>() };
p2.orders.Add(new Order() { OrderId = "Paul order 1" });
List<Person> L1 = new List<Person>();
L1.Add(p1);
L1.Add(p2);
// build list 2
Person p3 = new Person() { Id = "John", orders = new List<Order>() };
p3.orders.Add(new Order() { OrderId = "John order 2" });
List<Person> L2 = new List<Person>();
L2.Add(p3);
//output
List<Person> merged = new List<Person>();
merged = L1.Union(L2, new PersonComparer()).ToList();
foreach (var item in merged)
{
Console.WriteLine("Person ID: {0}", item.Id);
foreach (var order in item.orders)
{
Console.WriteLine(" -- {0}", order.OrderId);
}
Console.WriteLine("-----------------");
}
Console.ReadKey();
}
}
Output:
/************************************************************
* current output:
*
* Presone ID: John
* --- John order 1
* -------------------------
* Presone ID: Paul
* --- Paul order 1
* ------------------------
* Presone ID: John
* --- John order 2
*
*
* desired output:
*
* Presone ID: John
* --- John order 1
* --- John order 2
* -------------------------
* Presone ID: Paul
* --- Paul order 1
* ------------------------
*
Upvotes: 0
Views: 113
Reputation: 101731
Concat
the lists, group by PersonId
, then create a person for each group and concatenate the orders:
L1.Concat(L2)
.GroupBy(x => x.Id)
.Select(x => new Person
{
Id = x.Key,
Orders = x.SelectMany(g => g.Orders).ToList()
}).ToList();
You don't need Union
here because you don't want to remove the duplicates.Even if your comparer works, it will remove the duplicate persons and you will lose the Orders
.You need all Persons
grouped by their Ids.Then once you get the groups you can easily get orders of all the persons in the group into a list.
Upvotes: 2