2016-07-17 18 views
0

私は、さまざまなソースからのクラスの統計情報で構成された複合クラスです。複合クラスは、統計クラスのソートおよびランキングプロパティに基づいて「合計スコア」を取得します。次のように複合クラスの再利用可能な匿名ランキング機能

例えば、統計クラスがあってもよい。

public class StatsTypeA 
{ 
    public int PropAX { get; set; } 
    public int PropAXPoints { get; set; } 

    public int PropAY { get; set; } 
    public int PropAYPoints { get; set; } 
} 

複合クラスは、この例のようである:メインクラスで

class CompositeType 
{ 
    public StatsTypeA StatsA { get; set; } 
    public StatsTypeB StatsB { get; set; } 
    public int Id { get; set; } 
    public int TotalPoints 
    { 
     get 
     { 
      return StatsA.PropAXPoints + StatsA.PropAYPoints +     StatsB.PropBXPoints + StatsB.PropBYPoints; 
     } 
    } 
} 

、複合のリストが存在することになりますクラス内の各プロパティの値を持つクラス:

List<CompositeType> participants = new List<CompositeType>(); 

私はしたいそれらをランク付けし、ブルートフォースでそれを行うことはできますが、コードの束を繰り返さない方法を見つけることはできません。例えば、単一のプロパティをランク付けすることができるとと採点:

var statsX = composites.GroupBy(s => s.StatsA.PropAX, 
          s => s.Id, 
          (key, group) => (new 
          { 
           Stats = key, 
           Participants = group.ToList() 
          })) 
        .OrderBy(s => s.Stats); 
int points = 0; 
foreach (var statGroup in statsX) 
{ 
    var maxPoints = points + statGroup.Participants.Count * 2 - 2; 
    var thisPoints = (points + maxPoints)/2; 
    foreach (var id in statGroup.Participants) 
    { 
     composites.Single(data => data.Id == id).StatsA.PropAXPoints = points; 
    } 
    points = maxPoints + 2; 
} 

上記のLINQ文で匿名型を使用して、再利用可能な匿名関数を作成する方法はありますか?言い換えれば、どのように個々の統計的特性をランク付けするための単一の関数/拡張メソッドを持つことができますか?ここで

+0

匿名型をあきらめたい場合は、汎用拡張メソッドとStatsとParticipantsを含むクラスで実行できます。 – Warty

答えて

1

は私が思いついた汎用の方法です:

Action<IEnumerable<CompositeType>, Func<CompositeType, int>, Action<CompositeType, int>> compute = 
    (cs, f, a) => 
    { 
     var stats = 
      from c in cs 
      group c by f(c) into gs 
      orderby gs.Key 
      select new 
      { 
       Stats = gs.Key, 
       Participants = gs.ToList() 
      }; 

     stats.Aggregate(0, (points, statGroup) => 
     { 
      var maxPoints = points + statGroup.Participants.Count * 2 - 2; 
      var avgPoints = (points + maxPoints)/2; 
      statGroup.Participants.ForEach(c => a(c, avgPoints)); 
      return maxPoints + 2; 
     }); 
    }; 

今、私はこのようにそれを呼び出すことができます。

compute(composites, c => c.StatsA.PropAX, (c, p) => c.StatsA.PropAXPoints = p); 
compute(composites, c => c.StatsA.PropAY, (c, p) => c.StatsA.PropAYPoints = p); 
compute(composites, c => c.StatsB.PropBX, (c, p) => c.StatsB.PropBXPoints = p); 
compute(composites, c => c.StatsB.PropBY, (c, p) => c.StatsB.PropBYPoints = p); 

はあなたが後に何をしたということですか?

+0

美しい。ありがとうございました。 –

関連する問題