2016-07-17 67 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

如果您願意放棄匿名類型,則可以使用通用擴展方法和包含統計信息和參與者的類。 – 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

美麗。謝謝。 –