Programing

LINQ + Foreach 대 Foreach + If

lottogame 2021. 1. 5. 07:39
반응형

LINQ + Foreach 대 Foreach + If


부울 속성이 true로 설정된 개체에 대해서만 작업을 수행하여 개체 목록을 반복해야합니다. 이 코드 사이에서 토론 중입니다.

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

그리고이 코드

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

첫 번째 코드는 분명히 깨끗하지만 쿼리에 대해 한 번, foreach에 대해 한 번-목록을 두 번 반복 할 것이라고 생각합니다. 이것은 큰 목록이 아니므로 성능에 대해 지나치게 걱정하지는 않지만 두 번 반복한다는 생각은 나를 괴롭 힙니다.

질문 : 두 번 반복하지 않고 이것을 작성하는 깔끔하고 예쁜 방법이 있습니까?


Jon Skeet은 때때로 이것이 어떻게 작동하는지 설명하기 위해 실사 LINQ 데모를 수행합니다. 무대에 세 사람이 있다고 상상해보십시오. 왼쪽에는 셔플 된 카드 덱을 가진 한 사람이 있습니다. 가운데에는 레드 카드 만 통과하는 남자가 있고 오른쪽에는 카드를 원하는 남자가 있습니다.

오른쪽에있는 사람이 그 사람을 가운데로 찌릅니다. 가운데에있는 남자가 왼쪽에있는 남자를 찌릅니다. 왼편에있는 사람이 가운데에있는 사람에게 카드를 건네줍니다. 그것이 검은 색이라면, 중간에있는 남자는 그것을 바닥에 던지고 그가 레드 카드를 얻을 때까지 다시 찌르고, 그는 오른쪽에있는 남자에게 건네 준다. 그런 다음 오른쪽에있는 사람이 다시 가운데를 찌릅니다.

이것은 왼쪽에있는 사람이 카드가 떨어질 때까지 계속됩니다.

데크는 처음부터 끝까지 두 번 이상 통과하지 않았습니다. 그러나 왼쪽에있는 사람과 중간에있는 사람은 모두 52 장의 카드를 처리했고 오른쪽에있는 사람은 26 장의 카드를 처리했습니다. 카드에 총 52 + 52 + 26 작업이 있었지만 데크는 한 번만 반복되었습니다 .

"LINQ"버전과 "계속"버전은 동일합니다. 만약 당신이

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

그런 다음 데크에서 각 카드를 가져 오는 52 개의 작업, 각 카드가 검은 색인지 테스트하는 52 개의 작업, 레드 카드에 대해 작동하는 26 개의 작업이 있습니다. 정확히 똑같습니다.


대부분의 Linq 연산자 Where지연 및 지연 실행 을 지원하도록 구현됩니다 . 귀하의 예제에서 반환 된 IEnumerable 뒤에있는 Where열거자가 조건 자와 일치하는 항목을 찾을 때까지 목록을 열거하고 결과를 산출하며 다음 요소를 요청할 때만 계속 되기 때문에 목록은 한 번만 반복 됩니다.

코드 관점에서 .NET 용 로컬을 선언 할 수 있다고 주장 할 수 있지만 where를 사용하는 변형을 선호합니다 parameters.Where(p => p.Condition).

Jon Skeet의 Edulinq 시리즈는 적극 권장되며,이 중 일부를 읽으면 LINQ 연산자를 이해하는 데 도움이됩니다.


실제로 "두 번 반복"되는 것이 아닙니다. .Where절은 지연된 실행을 사용합니다. 즉,를 호출 할 때 실제로 작업이 수행되지 .Where않지만 결과를 반복하면 원래 목록을 반복하고 조건과 일치하는 항목 만 통과합니다. 코드가 실행되는 방식에 대해 생각해 보면 다음과 같이 효과적으로 수행하는 것입니다.

Func<Parameter, bool> matchesCondition = p => p.Condition;
foreach(var parameter in parameters)
{
    if(matchesCondition(parameter))
    {
        ...
    }
}

스타일 측면에서 개인적으로 다음과 같은 것을 선호합니다.

var matchingParameters = parameters.Where(p => p.Condition);
foreach(var parameter in matchingParameters)
{
}

나는 이것을 선호한다 :

theList.Where(itm => itm.Condition).ToList().ForEach(itmFE => { itmFe.DoSomething(); }); 

참조 URL : https://stackoverflow.com/questions/9072126/linq-foreach-vs-foreach-if

반응형