Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
206 views
in Technique[技术] by (71.8m points)

c# - LINQ + Foreach vs Foreach + If

I need to iterate over a List of objects, doing something only for the objects that have a boolean property set to true. I'm debating between this code

foreach (RouteParameter parameter in parameters.Where(p => p.Condition))
{ //do something }

and this code

foreach (RouteParameter parameter in parameters)
{ 
  if !parameter.Condition
    continue;
  //do something
}

The first code is obviously cleaner, but I suspect it's going to loop over the list twice - once for the query and once for the foreach. This won't be a huge list so I'm not overly concerned about performance, but the idea of looping twice just bugs me.

Question: Is there a clean/pretty way to write this without looping twice?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Jon Skeet sometimes does a live-action LINQ demo to explain how this works. Imagine you have three people on stage. On the left we have one guy who has a shuffled deck of cards. In the middle we have one guy who only passes along red cards, and on the right, we have a guy who wants cards.

The guy on the right pokes the guy in the middle. The guy in the middle pokes the guy on the left. The guy on the left hands the guy in the middle a card. If it is black, the guy in the middle throws it on the floor and pokes again until he gets a red card, which he then hands to the guy on the right. Then the guy on the right pokes the guy in the middle again.

This continues until the guy on the left runs out of cards.

The deck was not gone through from start to finish more than once. However, both the guy on the left and the guy in the middle handled 52 cards, and the guy on the right handled 26 cards. There were a total of 52 + 52 + 26 operations on cards, but the deck was only looped through once.

Your "LINQ" version and the "continue" version are the same thing; if you had

foreach(var card in deck)
{
    if (card.IsBlack) continue;
    ... use card ...

then there are 52 operations that fetch each card from the deck, 52 operations that test to see if each card is black, and 26 operations that act on the red card. Same thing exactly.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...