2017-01-30 1 views
1

목록별로 그룹화하려고 시도한 다음 각 그룹의 항목 수를 계산 한 다음 해당 수를 기반으로 각 그룹의 최대 값만 선택하려고합니다. 다음 코드는 올바르게 작동하고 필요한 부분을 수행합니다. 문제는 그것이 매우 느립니다, 특히 두 번째 단계입니다. 보다 효율적인 방법으로 동일한 결과를 얻을 수있는 방법을 알고 계십니까? 다음으로 정렬하여 그룹 수, 성능 문제로 최대 수를 선택하십시오.

var grouppedList = sourceList.Where(j => j.field1 == "1000") 
    .GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 }) 
    .Select(k => new 
    { 
     f4 = k.Key.f4, 
     mask = k.Key.mask, 
     f3 = k.Key.f3, 
     Total = k.Count() 
    }); 

var totalsList = grouppedList 
    .Where(i => !grouppedList.Any(j => 
         j.mask == i.mask && j.f4 == i.f4 && j.Total > i.Total)) 
    .ToList(); 
+0

첫 번째 섹션에서 목록을 만들려고 했으므로 한 번만 계산됩니다. –

+1

_ 초 단계 무엇입니까? 쿼리가 하나 뿐이므로 ToList에서 실행됩니다. –

+0

Thanks Tim! 이것은 정확히 문제였습니다. – Manngo

답변

2

귀하의 groupedListList 없습니다. IEnumerable입니다. 따라서 액세스 할 때마다 실행됩니다. 그리고 당신은 그것의 모든 부분을 위해 그것을 접근합니다 (Where 절에서). ,

var grouppedList = sourceList.Where(j => j.field1 == "1000") 
    .GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 }) 
    .Select(k => new 
    { 
     f4 = k.Key.f4, 
     mask = k.Key.mask, 
     f3 = k.Key.f3, 
     Total = k.Count() 
    }).ToList(); 

또 다른 가능성은 그룹화하고 총과 아이템을 얻는 결합하는 것입니다 나는 그것을이 같은 것을 할 것이다 : 나는 (한 번만 쿼리를 실행)에서 목록을 만들 제안

var grouppedList = sourceList.Where(j => j.field1 == "1000") 
.GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 }) 
.Select(k => new 
{ 
    f4 = k.Key.f4, 
    mask = k.Key.mask, 
    f3 = k.Key.f3, 
    Total = k.Count() 
}) 
.GroupBy(x => new {x.mask, x.f4}) 
.Select(x=>x.OrderBydescending(t=>t.Total).First()); 
.ToList(); 
+0

@Manngo 그것이 당신을 도운다면, 나는 upvote에 대한 thankfull 것입니다 :) –

+0

나는 분명히 두 번째 접근 방식 (또는 비슷한) +1을 사용합니다 –

1

이 코드가 느린 이유는 아마 grouppedList을 두 번 반복한다는 사실입니다.

var totalsList = grouppedList.Where(i => !grouppedList.Any(
    j => j.mask == i.mask && j.f4 == i.f4 && j.Total > i.Total) 
).ToList(); 

groppuedList의 모든 요소에 대한 내부 Where -statement에 groppedList을 반복 할 것이다. 당신은 eample에 대한 ToList으로 즉시 실행을 강제로 고려할 수 :

var grouppedList = sourceList.Where(j => j.field1 == "1000") 
.GroupBy(i => new { mask = i.field2.Substring(0, 1), f3 = i.field3, f4 = i.field4 }) 
.Select(k => new 
{ 
    f4 = k.Key.f4, 
    mask = k.Key.mask, 
    f3 = k.Key.f3, 
    Total = k.Count() 
}).Tolist(); // this forces an immediate execution of your select-statement 

당신이 지금이 (가) allready 대신 다시 쿼리를 다시 실행의 목록을 구체화 사용하는 두 번째 문

var totalsList = grouppedList.Where(i => !grouppedList.Any(j => j.mask == i.mask && j.f4 == i.f4 && j.Total > i.Total)).ToList(); 

를 호출 할 때.

관련 문제