2017-01-30 4 views
1

リストでグループ化し、各グループの項目を数え、その数に基づいて各グループの最大値のみを選択します。次のコードは機能し、私が必要とするものを正確に行います。問題は、それが非常に遅いことです。特に2番目のステップです。より効率的な方法で同じ結果を達成する方法を知っていますか? 順番に並べ替え、グループ別の最大値、パフォーマンスの問題を選択してください。

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回だけ行われるようにしましたか? –

+1

_second_ステップは何ですか?クエリが1つしかなく、ToListで実行されます –

+0

ありがとう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

私は間違いなく2番目のアプローチ(または同様の)を使用する+1 –

1

このコードが遅いように見える理由は、恐らく、grouppedListを2回繰り返しているということでしょう。

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 

あなたは今、それが出回っ代わりに、何度も何度もクエリを実行するのリストをマテリアを使用する2番目の文

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

を呼び出すとき。

関連する問題