简体   繁体   English

如何使用LINQ或Lambda代替嵌套和多个foreach语句

[英]How to use LINQ or Lambda instead of nested and multiple foreach statements

How can I use LINQ or Lambda instead of nested and multiple foreach statements. 如何使用LINQ或Lambda代替嵌套和多个foreach语句。

I want to use a better syntax than nested foreach statements to overwrite the initial list with items from the second list. 我想使用比嵌套的foreach语句更好的语法来用第二个列表中的项目覆盖初始列表。

In the code below: 在下面的代码中:

  • I want to overwrite initialList with those in secondList that have the same Value. 我想用secondList中具有相同Value的那些覆盖initialList。 (Remove Red) (删除红色)
  • Use the items in secondList where Value was the same (Yellow) New initialList list should include (Green and Yellow) 使用secondList中值相同的项目(黄色)新的initialList列表应包括(绿色和黄色)

     static void Main(string[] 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 = new List<Person>(); initialList.Add(person1); initialList.Add(person2); var secondList = new List<Person>(); secondList.Add(person3); List<Person> personsToRemove = new List<Person>(); List<Person> personsToUpdate = new List<Person>(); foreach (var pers1 in initialList) { foreach (var pers2 in secondList) { if (pers1.Value == pers2.Value) { personsToRemove.Add(pers1); personsToUpdate.Add(pers2); } } } foreach (var remPers in personsToRemove) { initialList.Remove(remPers); } foreach (var updPers in personsToUpdate) { initialList.Add(updPers); } foreach (var item in initialList) { Console.WriteLine(String.Format("Value: {0}, prodId: {1}, domainId: {2}, Name: {3}", item.Value, item.prodId, item.domainId, item.Name)); } Console.ReadKey(); } public class Person { public int prodId { get; set; } public string Value { get; set; } public int domainId { get; set; } public string Name { get; set; } } 

Your nested loops are most efficiently represented with a join . 您的嵌套循环最有效地用join表示。 In addition, it would be helpful efficiency-wise to not have to do a linear-search on the entire list just to remove an element and then to add a new one in. There is an overload of Enumerable.Select() we can use to embed the item index in the result, so that the element can simply be replaced directly. 此外,从效率角度考虑,不必在整个列表上进行线性搜索即可删除一个元素,然后再添加一个新元素。这对我们Enumerable.Select()有很多重载将项目索引嵌入到结果中,以便可以简单地直接替换元素。

Putting it all together, it looks like this: 放在一起,看起来像这样:

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

The above code replaces the original code starting with the declarations of the personsToRemove and personsToUpdate lists, and the first three foreach loops (ie all but the one that displays the final result). 上面的代码替换了原始代码,从personsToRemovepersonsToUpdate列表的声明开始,以及前三个foreach循环(即显示最终结果的循环除外)。

Notes: 笔记:

  • From the initialList , the code synthesizes an anonymous type containing the Person instance and the index of that instance in the list. 该代码从initialList合成一个匿名类型,该类型包含Person实例和该实例在列表中的索引。
  • The join clause pairs up all of the items from each list where the Value properties are equal. join子句将每个列表中Value属性相等的所有项配对。

Important: if there are multiple elements in either list with the same Value property, they are each paired with every other element in the other list having that same Value . 重要提示:如果任一列表中有多个具有相同Value属性的元素,则它们将与另一个列表中具有相同Value每个其他元素配对。 Ie if initialList has two elements having the Value of "foo" and secondList has three such elements, you will wind up with six elements in the resulting join. 也就是说,如果initialList具有两个要素Value “富”和secondList有三个这样的元素,你会风与中产生的加入六大要素。 Your question does not define whether this is possible, nor what you would want to happen if it were, so I've just ignored that possibility here. 您的问题并没有定义这是否可能,如果可能,您将要发生什么,因此在这里我只是忽略了这种可能性。 :) :)

  • The join result is projected to a new anonymous type containing the index of the element to be replaced, and the new value. join结果投影到一个新的匿名类型,其中包含要替换的元素的索引和新值。
  • The query result is materialized by calling ToList() . 通过调用ToList()查询结果。 This is necessary because the join is otherwise deferred and modifying the initialList would invalidate the query. 这是必要的,因为否则将推迟连接,并且修改initialList将使查询无效。
  • Of course, in the remaining foreach all that the code then needs to do is assign to the appropriate index position in the list the replacement value determined by the query. 当然,在其余foreach所有的代码,然后需要做的是分配给替换值确定由查询列表中相应的索引位置。

You can use Generics as well. 您也可以使用泛型。 Below is the short code will work for you: 以下是适合您的简短代码:

    initialList.ForEach(p =>
    {
        if (secondList.Any(sp => sp.Value == p.Value))
        {
            initialList.Remove(p);
            initialList.Add(secondList.Single(spu => spu.Value == p.Value));
        };
    });

如何使用 linq 而不是 foreach 来获取列表<object><div id="text_translate"><pre> public List<object> Query() { List<string> availableBillingIncrements = _controller.GetAvailableDropdowns().AvailableBillingIncrement; List<object> results = new List<object>(); var x = availableBillingIncrements.Select(i => new List<object> { "Increment", i }).ToList().Select(i => new List<object> { i }).ToList(); foreach (string increment in availableBillingIncrements) { List<object> result = new List<object>(); result.Add(new List<object> { "Increment", increment }); results.Add(result); } return results; }</pre><p> 在上面的代码中,x 和 results 是相同的对象,除了 x 的类型是 List<List<object>> 并且 results 是 List<object>。 如何摆脱 foreach 循环并使用 x 作为结果?</p></div></object> - how to use linq instead of foreach to get an List<object>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在这种情况下,如何避免通过使用lambda或linq来使用嵌套的foreach语句? - How do I avoid using nested foreach statements by using lambda or linq in this scenario? LINQ而不是嵌套的foreach和if - LINQ instead of nested foreach and if 如何在带有2条语句的linq lambda中使用sql IN语句 - How to use sql IN statement in linq lambda with 2 statements 嵌套 Lambda 表达式而不是 foreach - Nested Lambda expression instead of foreach 如何使用Linq代替foreach进行分组和计数 - How to use Linq instead of foreach to Group and Count 使用Linq展平嵌套列表而不是foreach循环 - Use Linq to flatten a nested list instead of a foreach loop LINQ表达式而不是嵌套的foreach循环 - LINQ expression instead of nested foreach loop LINQ表达式而不是嵌套的foreach循环 - LINQ expression instead of nested foreach loops 如何使用 linq 而不是 foreach 来获取列表<object><div id="text_translate"><pre> public List<object> Query() { List<string> availableBillingIncrements = _controller.GetAvailableDropdowns().AvailableBillingIncrement; List<object> results = new List<object>(); var x = availableBillingIncrements.Select(i => new List<object> { "Increment", i }).ToList().Select(i => new List<object> { i }).ToList(); foreach (string increment in availableBillingIncrements) { List<object> result = new List<object>(); result.Add(new List<object> { "Increment", increment }); results.Add(result); } return results; }</pre><p> 在上面的代码中,x 和 results 是相同的对象,除了 x 的类型是 List<List<object>> 并且 results 是 List<object>。 如何摆脱 foreach 循环并使用 x 作为结果?</p></div></object> - how to use linq instead of foreach to get an List<object> 如何在C#中使用linq代替foreach循环 - How to use linq instead of foreach loop in c#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM