嵌套的foreach没有给出正确的结果

时间:2017-04-27 14:12:14

标签: linq foreach

我有一个程序应该返回玩家在多个项目中积累的积分。积分的计算基于参与特定参与关系的人数,参与者在该参与中的排名。

我目前正在运行此代码:

foreach (var player in players)
{
    singleCircuitPoints result = new singleCircuitPoints();
    result.player = player.play;
    result.team = player.team;

    var circuits = 
        (from r in unitOfWork.RegistrationRepository.Get(
                     includeProperties: "competition,player")
          where 
              r.competition.startDate.Year == competition.startDate.Year 
              && r.competition.beach == true 
              && r.competition.startDate <= competition.startDate 
              && r.corporate == corp 
              && r.player.pGender == gender 
              && r.partnerId == null
         select r.competition);

    int playerPoints = 0;
    int numPlayers = 0;
    List<int> list = new List<int>();

    foreach (Competition c in circuits)
    {
        if (player.play.registrations.Any(p => p.compId == c.compId))
        {
            var circuit = from a in allCircuits 
                          where a.compId == c.compId select a;

            numPlayers = circuit.Count();

            list = circuit.OrderBy(r => r.score.Sum())
                          .ThenBy(r => r.orderedStroke)
                          .Select(r => r.pId).ToList();

            for (int x = 0; x < list.Count(); x++)
            {
                int pos = list.IndexOf(player.play.pId);
                playerPoints = numPlayers - pos;
            }
        }
        else
        {
            playerPoints = 0;
        }
        result.points += playerPoints;
    }
    results.Add(result);
}

代码存在以下问题:

  1. 需要花费大量时间处理。
  2. 每次参与后都不会积累玩家的积分。
  3. 期待您的帮助。

2 个答案:

答案 0 :(得分:0)

此代码

for (int x = 0; x < list.Count(); x++)
            {
                int pos = list.IndexOf(player.play.pId);
                playerPoints = numPlayers - pos;
            }

每次都会分配变量playerPoints,所以在for循环结束后,它将具有list

中最后一项的值

我认为你需要像

这样的东西
playerPoints = 0;
for (int x = 0; x < list.Count(); x++)
            {
                int pos = list.IndexOf(player.play.pId);
                playerPoints += numPlayers - pos;
            }

至于表现

我可以在你的代码中看到你为每个玩家计算变量circuits但没有使用任何与此玩家相关的信息..所以你可以在进入foreach之前计算一次

答案 1 :(得分:0)

谢谢Modar Na,你的建议对我有用。另外,我不得不打电话给yield return来返回积分。

代码是:

foreach (var p in players)
                        {
                        singleCircuitPoints result = new singleCircuitPoints();

                        result.player = p.play;
                        result.team = p.team;
                        result.points = _calculatePoints(p.play, allCircuits).LastOrDefault();
                        results.Add(result);`

_calculatePoints方法如下:

public IEnumerable<int> _calculatePoints(Player player, IEnumerable<Registration> circuits)
        {
        int points = 0;
        foreach (Competition c in circuits.Where(c => c.pId == player.pId).Select(r => r.competition))
            {
            if (player.registrations.Any(p => p.compId == c.compId))
                {
                var circuit = from a in circuits where a.compId == c.compId select a;
                int numPlayers = circuit.Count();
                List<int> list = circuit.OrderBy(r => r.score.Sum()).ThenBy(r => r.orderedStroke).Select(r => r.pId).ToList();
                int pos = list.IndexOf(player.pId);
                yield return points += numPlayers - pos;
                }
            else
                {
                yield return points += 0;
                }
            }
        }

留下了缓慢表现的挑战。