C# 合并两个列表<;T>;使用LINQ基于实例成员合并T的实例
我有一个名为NamedEntity的抽象类(由各种不同的子类覆盖):C# 合并两个列表<;T>;使用LINQ基于实例成员合并T的实例,c#,.net,linq,generics,join,C#,.net,Linq,Generics,Join,我有一个名为NamedEntity的抽象类(由各种不同的子类覆盖): public抽象类NamedEntity其中T:TweetModel { 受保护的字符串\u名称; 公共抽象字符串名称{get;set;} 公共摘要列表tweets{get;set;} } 这个类中的关键元素是列表,它包含一个Tweet对象列表,用于对与Tweet相关的基本元数据(即文本、作者、日期/时间等)进行建模 如何组合两个列表,以便根据Name属性的匹配值将一个列表中的项目合并到另一个列表中 即NamedEntity
public抽象类NamedEntity其中T:TweetModel
{
受保护的字符串\u名称;
公共抽象字符串名称{get;set;}
公共摘要列表tweets{get;set;}
}
这个类中的关键元素是列表
,它包含一个Tweet对象列表,用于对与Tweet相关的基本元数据(即文本、作者、日期/时间等)进行建模
如何组合两个列表
,以便根据Name属性的匹配值将一个列表中的项目合并到另一个列表中
即NamedEntity1的名称为“伦敦”+相关tweets,NamedEntity2的名称为“伦敦”和不同的列表。如何合并这两个集合,然后从两个集合中提取列表
实例,并将它们添加到新的列表
对象中
我已经读到我可以在这里使用连接,但我并不真正理解LINQ语法:
private List<NamedEntity<TweetModel>> joinLists(List<NamedEntity<TweetModel>> list1, List<NamedEntity<TweetModel>> list2)
{
//var joined = from Name in list1 join Name in list2 on ????;
}
私有列表joinlist(列表列表1、列表列表2)
{
//var join=从列表1中的名称在???上连接列表2中的名称????;
}
有三件事你需要告诉加入
:加入哪些集合,通过什么和如何实际加入它们:
private IEnumerable<NamedEntity<TweetModel>> Join(
IEnumerable<NamedEntity<TweetModel>> list1,
IEnumerable<NamedEntity<TweetModel>> list2)
{
return list1.Join(list2, item => item.Name, item => item.Name, (outer, inner) =>
{
outer.tweets.AddRange(inner.tweets);
return outer;
});
}
私有IEnumerable连接(
IEnumerable列表1,
IEnumerable列表2)
{
返回list1.Join(list2,item=>item.Name,item=>item.Name,(外部,内部)=>
{
外部.tweets.AddRange(内部.tweets);
返回外部;
});
}
您可以使用Union()
组合这两个列表
,按名称
对它们进行分组,并使用tweets
属性选择新对象,该属性填充了相应组中所有tweets
的组合:
private List<NamedEntity<TweetModel>> joinLists(List<NamedEntity<TweetModel>> list1, List<NamedEntity<TweetModel>> list2)
{
List<NamedEntity<TweetModel>> joined;
joined = list1.Union(list2)
.GroupBy(o => o.Name)
.Select(o => new NamedEntity<TweetModel>
{
Name = o.Key,
tweets =
o.SelectMany(x => x.tweets).ToList()
}).ToList();
return joined;
}
私有列表joinlist(列表列表1、列表列表2)
{
加入名单;
joined=list1.Union(list2)
.GroupBy(o=>o.Name)
.选择(o=>新名称身份
{
名称=o.键,
推特=
o、 选择many(x=>x.tweets).ToList()
}).ToList();
回归加入;
}
这样可以避免在某种情况下丢失一些NamedEntity
s,例如,当示例中的NamedEntity1
和NamedEntity2
位于相同的列表中时。对于普通LINQ连接(因为它基本上是一个内部连接),将只返回两个列表中都存在Name
的NamedEntity
。您始终可以选择只使用嵌套的传统foreach循环。您甚至可以创建一个扩展方法来合并两个列表:
public static class NamedEntityExtensions
{
public static IList<NamedEntity<T>> MergeEntities<T>(this IList<NamedEntity<T>> list1, IList<NamedEntity<T>> list2)
where T: TweetModel
{
foreach(NamedEntity<T> entity1 in list1)
{
foreach(NamedEntity<T> entity2 in list2)
{
if(entity1.Name == entity2.Name)
{
entity1.Tweets.AddRange(entity2.Tweets);
}
}
}
return list1; //original list will get augmented but returning it allows chaining
}
}
此方法还支持将调用链接到两个以上的列表:
list1.MergeEntities(list2).MergeEntities(list3);
如果您不想实际修改原始列表1,则始终可以在扩展方法内部生成一个新列表,而不是添加到原始列表中
注意:只有当列表1包含您关心的所有不同的“Name”值时,这才有效。需要添加额外的逻辑,才能从仅存在于列表2中的实体创建新项。如何解决无法在中创建(抽象)NamedEntity类实例的问题。选择表达式?
list1.MergeEntities(list2);
list1.MergeEntities(list2).MergeEntities(list3);