LINQ Join 2 List s

Prefacio: no entiendo lo que hace esto:

o => o.ID, i => i.ID, (o, id) => o 

As√≠ que no me molestes. ūüôā


Tengo 2 listas que necesito unir:

 // list1 contains ALL contacts for a customer. // Each item has a unique ID. // There are no duplicates. ContactCollection list1 = myCustomer.GetContacts(); // list2 contains the customer contacts (in list1) relevant to a REPORT // the items in this list may have properties that differ from those in list1. /*****/// eg: /*****/ bool SelectedForNotification; /*****/// may be different. ContactCollection list2 = myReport.GetContacts(); 

Necesito crear un tercer ContactCollection que contenga todos los contactos en list1 pero con las propiedades de los artículos en list2 , si el artículo está en la lista [2] ( list3.Count == list1.Count ).


Necesito reemplazar todos los artículos en list1 con los artículos en list2 donde los artículos en list1 tienen los ID de los artículos en list2 . La lista resultante ( list3 ) debe contener la misma cantidad de elementos en la list1 .

Siento que no tengo ning√ļn sentido. Por lo tanto, haga preguntas en los comentarios e intentar√© aclarar.

Las uniones no son tan difíciles, pero su problema probablemente podría usar alguna explicación adicional.

Para unir dos listas, podrías hacer algo como

 var joined = from Item1 in list1 join Item2 in list2 on Item1.Id equals Item2.Id // join on some property select new { Item1, Item2 }; 

esto dar√° un IEnumerable<'a> , donde’ a es un tipo an√≥nimo que contiene un elemento de list1 y su elemento relacionado de list2. A continuaci√≥n, puede elegir qu√© propiedades de los objetos usar seg√ļn sea necesario.

Para obtener el resultado a una lista concreta, todo lo que se necesita es una llamada a .ToList (). Puedes hacer eso como

 var list3 = joined.ToList(); // or var list3 = (from Item1 in list1 join Item2 in list2 on Item1.Id equals Item2.Id // join on some property select new { Item1, Item2 }).ToList(); 

Para hacer una combinación a la izquierda para seleccionar todos los elementos de list1 incluso sin una coincidencia en list2, puede hacer algo como esto

 var list3 = (from Item1 in list1 join Item2 in list2 on Item1.Id equals Item2.Id // join on some property into grouping from Item2 in grouping.DefaultIfEmpty() select new { Item1, Item2 }).ToList(); 

Esto le dará una lista en la que el Artículo1 es igual al elemento de la primera lista y el Artículo2 igualará el elemento coincidente de la segunda lista o el valor predeterminado, que será nulo para un tipo de referencia.

Esto es lo que se me ocurrió (basado en esto ):

  List list3 = (from item1 in list1 join item2 in list2 on item1.ContactID equals item2.ContactID into g from o in g.DefaultIfEmpty() select o == null ? item1 :o).ToList(); 

Mi parte favorita es la carita sonriente

:o)

¬°Gracias por tu ayuda!

Aquí hay un DotNetFiddle con un Linq Group Join

 using System; using System.Collections; using System.Collections.Generic; using System.Linq; class Order { public int Id; public string Name; public Order(int id, string name) { this.Id = id; this.Name = name; } } class OrderItem { public int Id; public string Name; public int OrderId; public OrderItem(int id, string name, int orderId) { this.Id = id; this.Name = name; this.OrderId = orderId; } } List orders = new List() { new Order(1, "one"), new Order(2, "two") }; List orderItems = new List() { new OrderItem(1, "itemOne", 1), new OrderItem(2, "itemTwo", 1), new OrderItem(3, "itemThree", 1), new OrderItem(4, "itemFour", 2), new OrderItem(5, "itemFive", 2) }; var joined = from o in orders join oi in orderItems on o.Id equals oi.OrderId into gj // gj means group join and is a collection OrderItem select new { o, gj }; // this is just to write the results to the console string columns = "{0,-20} {1, -20}"; Console.WriteLine(string.Format(columns, "Order", "Item Count")); foreach(var j in joined) { Console.WriteLine(columns, joName, j.gj.Count() ); } 

Parece que en realidad no necesitas un full-join. En su lugar, puede hacer una semi-unión, verificando cada contacto en la lista 2 para ver si está en la lista 1:

ContactCollection list3 = list2.Where(c => list1.Contains(c));

No s√© cu√°n grandes son sus listas, pero tenga en cuenta que este enfoque tiene O (n m) complejidad a menos que list1 est√© ordenado o sea compatible con b√ļsquedas r√°pidas (como en un hashset), en cuyo caso podr√≠a ser tan eficiente como O (n log (m)) o reescrito como merge-join y ser O (n).