将循环逻辑转换为LINQ

时间:2015-04-21 20:54:13

标签: c# linq c#-4.0

有没有人知道这样做是否更简洁(可能是LINQ)?我想将值分组到bucket中,并给它一个分数,例如在下面的代码中,如果值为:

  • 小于或等于5,将得分提高1
  • 10及以下,将分数提高2
  • 15及以下,将分数提高3
  • 否则增加4。

我必须完成大约10个属性,并且每个属性都有不同的评分范围。

public static PScore GetScore(IEnumerable<PStat> rs)
    {
        var data = new PScore();

        foreach(var item in rs)
        {
            if(item.Kill <= 5)
            {
                data.Kills++;
            }
            else if (item.Kill <= 10)
            {
                data.Kills += 2;
            }
            else if (item.Kill <= 15)
            {
                data.Kills += 3;
            }
            else
            {
                data.Kills += 4;
            }
        }

        return data;
    }

修改#1 谢谢大家,范围也各不相同,我有10个属性循环,所以我使用它并传递了值和范围

public static int GetScoreASC(int value, int[] range)
    {

        if (value <= range[0])
        {
            return 1;
        }
        else if (value <= range[1])
        {
            return 2;
        }
        else if (value <= range[2])
        {
            return 3;
        }
        else if (value <= range[3])
        {
            return 4;
        }
        else if (value <= range[4])
        {
            return 5;
        }
        else if (value <= range[5])
        {
            return 6;
        }
        else if (value <= range[6])
        {
            return 7;
        }
        else if (value <= range[7])
        {
            return 8;
        }
        else if (value <= range[8])
        {
            return 9;
        }
        else
        {
            return 10;
        }
    }

这样我可以为所有属性重用相同的方法。

2 个答案:

答案 0 :(得分:3)

我会使用LINQ对每个属性进行一些数学运算:

public static PScore GetScore(IEnumerable<PStat> rs)
{
   var data = new PScore();
   data.Kills = rs.Sum(item => Math.Min(item.Kill / 5 + (item.Kill % 5 == 0 ? 0 : 1), 4));
   return data;
}

答案 1 :(得分:3)

您可以使用Select抓取Kill中的rs值,然后Sum来汇总这些值,从而减少自己的重复次数。

public static PScore GetScore(IEnumerable<PStat> rs)
{
    return new PScore
    {
        Kills = rs.Select(item => item.Kill).Sum(kill =>
        {
            if (kill <= 5) return 1;
            if (kill <= 10) return 2;
            if (kill <= 15) return 3;
            return 4;
        })
    };
}

如果您喜欢Konrad将条件转换为闭合形式计算的风格,则需要稍微纠正其公式。不过,我个人会坚持使用条件。

public static PScore GetScore(IEnumerable<PStat> rs)
{
    return new PScore
    {
        Kills = rs.Select(item => item.Kill)
            .Sum(kill => Math.Max(1, Math.Min((kill + 4) / 5, 4)));
    };
}