C# 如何使用LINQ或Lambda代替嵌套和多个foreach语句
如何使用LINQ或Lambda代替嵌套和多个foreach语句 我想使用比嵌套的foreach语句更好的语法,用第二个列表中的项覆盖初始列表 在下面的代码中:C# 如何使用LINQ或Lambda代替嵌套和多个foreach语句,c#,linq,loops,lambda,C#,Linq,Loops,Lambda,如何使用LINQ或Lambda代替嵌套和多个foreach语句 我想使用比嵌套的foreach语句更好的语法,用第二个列表中的项覆盖初始列表 在下面的代码中: 我想用secondList中具有相同值的值覆盖initialList。(删除红色) 使用第二个列表中值相同(黄色)的项目 新的初始列表应包括(绿色和黄色) static void Main(字符串[]args) { int-useProd=2; int useDomain=0; var person1=new Person(){prod
- 我想用secondList中具有相同值的值覆盖initialList。(删除红色)
- 使用第二个列表中值相同(黄色)的项目
新的初始列表应包括(绿色和黄色)
static void Main(字符串[]args) { int-useProd=2; int useDomain=0; var person1=new Person(){prodId=1,Value=“foo”,domainId=0,Name=“Red”}; var person2=new Person(){prodId=1,Value=“bar”,domainId=0,Name=“Green”}; var person3=new Person(){prodId=1,Value=“foo”,domainId=1,Name=“Yellow”}; var initialList=新列表(); 初始列表。添加(人员1); 初始列表。添加(人员2); var secondList=新列表(); 第二个列表。添加(人员3); List personsToRemove=新列表(); List personsToUpdate=新列表(); foreach(初始列表中的变量pers1) { foreach(第二个列表中的var pers2) { if(pers1.Value==pers2.Value) { personsToRemove.Add(pers1); 人员更新。添加(人员2); } } } foreach(个人储蓄中的var利息) { 初始列表。删除(remPers); } foreach(个人更新中的var updPers) { 初始列表。添加(updPers); } foreach(初始列表中的变量项) { WriteLine(String.Format(“Value:{0},prodId:{1},domainId:{2},Name:{3}”,item.Value,item.prodId,item.domainId,item.Name)); } Console.ReadKey(); } 公共阶层人士 { public int prodId{get;set;} 公共字符串值{get;set;} 公共int域ID{get;set;} 公共字符串名称{get;set;} }
连接来最有效地表示。此外,不必在整个列表上进行线性搜索,只需删除一个元素,然后在列表中添加一个新元素,这将有助于提高效率。有一个超负荷的Enumerable.Select()
我们可以用来在结果中嵌入项索引,这样就可以直接替换元素
综上所述,它看起来是这样的:
var join = from p1 in initialList.Select((p, i) => new { Person = p, Index = i })
join p2 in secondList on p1.Person.Value equals p2.Value
select new { Index = p1.Index, Replacement = p2 };
foreach (var item in join.ToList())
{
initialList[item.Index] = item.Replacement;
}
上述代码将替换原始代码,从personsToRemove
和PersonToUpdate
列表的声明开始,以及前三个foreach
循环(即除显示最终结果的循环外的所有循环)
注:
- 从
initialList
中,代码合成一个匿名类型,其中包含Person
实例和列表中该实例的索引
join
子句将值
属性相等的每个列表中的所有项目配对
重要提示:如果任一列表中有多个元素具有相同的值
属性,则它们将分别与另一个列表中具有相同值的所有其他元素配对。也就是说,如果initialList
有两个元素具有Value
的“foo”和secondList
有三个这样的元素,那么在生成的联接中将有六个元素。你的问题没有定义这是否可能,也没有定义如果可能,你希望发生什么,所以我在这里忽略了这种可能性。:)
join
结果被投影到一个新的匿名类型,其中包含要替换的元素的索引和新值
- 查询结果通过调用
ToList()
来具体化。这是必要的,因为连接会被延迟,修改初始列表将使查询无效
- 当然,在剩下的
foreach
中,代码接下来需要做的就是将查询确定的替换值分配给列表中适当的索引位置
您也可以使用泛型。以下是适用于您的简短代码:
initialList.ForEach(p =>
{
if (secondList.Any(sp => sp.Value == p.Value))
{
initialList.Remove(p);
initialList.Add(secondList.Single(spu => spu.Value == p.Value));
};
});
我几乎可以肯定,这个问题应该在中,而不是StackOverflow。代码没有显示任何解决问题的尝试,它只是创建了两个列表。你试过什么吗?你遇到问题了吗?您是否检查了面向集合的方法Enumerable.Union、Enumerable.Except等?@Patrick因为这似乎是示例代码,所以不适合进行代码检查。它将被关闭topic@Heslacher哦,我想用foreachs解决了这个问题,并试图将它改为linq,但因为它没有显示foreachs,所以你可能应该right@Niike2如果你在codereview上发表文章,你可以尽可能多地发表原始foreach,并询问如何将其更改为linq/lambda,我们会这样做乐意帮助你。
initialList.ForEach(p =>
{
if (secondList.Any(sp => sp.Value == p.Value))
{
initialList.Remove(p);
initialList.Add(secondList.Single(spu => spu.Value == p.Value));
};
});