LINQ加入2列表

前言:我不明白这是做什么的:

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

所以对我很轻松。 🙂


我有2个列表需要连接在一起:

 // 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(); 

我需要创建第三个ContactCollection,其中包含list1中的所有联系人,但是如果项目在列表[2]( list3.Count == list1.Count )中,则包含list2项目的属性。


我需要将list1所有项目替换为list2中的项目,其中list1中的项目具有list2中项目的ID。 结果列表( list3 )应该包含list1相同数量的项目。

我觉得好像没有任何意义。 所以,请在评论中提问,我会尽力澄清。

加入并不是那么困难,但你的问题可能会使用一些进一步的解释。

要加入两个列表,您可以执行类似的操作

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

这将给出一个IEnumerable<'a> ,其中’a是一个匿名类型,它包含list1中的一个项目及其与list2相关的项目。 然后,您可以根据需要选择要使用的对象属性。

要将结果输出到具体列表,只需要调用.ToList()即可。 你可以这样做

 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(); 

要进行左连接以从list1中选择所有元素,即使list2中没有匹配,也可以执行类似的操作

 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(); 

这将为您提供一个列表,其中Item1等于第一个列表中的项目,Item2将等于第二个列表中的匹配项默认值,对于引用类型,它将为null。

这是我想出的(基于此 ):

  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(); 

我最喜欢的部分是大鼻子的笑脸

:o)

谢谢你的帮助!

这是一个带有Linq Group Join的DotNetFiddle

 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() ); } 

看起来你真的不需要完全加入。 您可以改为执行半连接,检查列表2中的每个联系人以查看它是否包含在列表1中:

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

我不知道你的列表有多大,但请注意, 除非list1被排序或支持快速查找(如在hashset中),否则这种方法具有O(n m)复杂度,在这种情况下,它可以像O(n)一样高效 log(m))或重写为merge-join,为O(n)。