2009-04-05 17 views
2

リスト上のwhere句の結果を取得し、その結果セットを取得して、元のクエリの集計から構築されたすべてのフィールドを持つ新しいタイプを1つだけ作成します。 。だから、以下の基本的な例を考えれば、2つのlinq文を1つにまとめるにはどうしようもないだろうか?元の場所に行がない場合、nullを返す必要があります。ありがとう!Linq - 別のクエリの結果を集計する方法

class Foo 
    { 
     public int A { get; set; } 
     public int B { get; set; } 
    } 
    List<Foo> lst = GetFooList(); 

     var q = (from f in lst 
       where f.A > 3 
       select f).ToList(); 
     if (q.Count != 0) 
     { 
      var qq = new 
      { 
       MinA = q.Min(l => l.A), 
       MaxB = q.Max(h => h.B), 
      }; 
      // now do something with qq 
     } 

アップデート:私の状況については 、元のセットは、アイテムの多くを持っていますが、WHERE句の後に、結果セットは非常に小さいです。 2番目のセットを数回列挙することは問題ではないはずです。また、これらのレコードから値を取得するために、セットの最初と最後を使用する必要があります。答えのグループは私にとって最も効果的です。集計方法は非常に興味深いですし、私は、そのための別の用途を持っていると思います。

+0

を返します。あなたはその最初の要素を消費しました。私はラウンドの方法があります疑いがあるが、それはハック...もっと思いますビットである可能性が高いです。 –

答えて

2
(from f in GetFooList() 
    where f.A > 3 
    group f by 1 into g 
    let MinA=g.Min(l=>l.A) 
    let MaxB=g.Max(h=>h.B) 
    select new {MinA, MaxB}).SingleOrDefault() 
+1

これはうまくいきますが、これはリスト全体を2回繰り返します:g.Min()とg.Max()、そして元の解決方法も同様です。 – Lucas

+0

...実際に3回、最初のものGROUPBY() – Lucas

9

このソリューションはリストをAggregate()で1回だけ反復しますが、空のリストの場合はシード値を返します。 Math.Min(int.MaxValue, C)は常にCを返すと同様にMath.Max(int.MinValue, C)ますのでところで、シード値はint.MaxValueint.MinValueあり、常に時間によってあなたは要素があるかどうかをテストしてみたので、それは比較的トリッキーだC.

var b = lst.Where(f => f.A > 3) 
      .Aggregate(
        // seed, initial values 
        new 
        { 
        MinA = int.MaxValue, 
        MaxB = int.MinValue 
        }, 

        // accumulator function 
        (a,f) => new 
        { 
        MinA = Math.Min(a.MinA , f.A), 
        MaxB = Math.Max(a.MaxB , f.B) 
        }); 
関連する問題