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)。