如何在C#中的Linq聚合中添加条件?

凯文·塔努贾(Kevin Tanudjaja)

我正在尝试使用命令式风格的Linq,但是无法将此条件在Aggregate内部转换为Linq。

考虑以下两个示例。

简单的例子:

public enum Color {
    Red,  // Red score = 10
    Yellow,  // Yellow score = 5
    Green,  // Green score = 2
}

//Populate our sample list
public List<Color> Colors = new List<Color> {Red, Green, Green, Yellow};

//I need help on this one
public float Score => Colors.Aggregate(0.0f, (total, next) => 
{
    //How to properly use conditional inside Aggregate?
    if (next == Color.Red) {
        return total + 10.0f;
    } else if (next == Color.Yellow) {
        return total + 5.0f;
    } else if (next == Color.Green) {
        return total + 2.0f;
    }
    //edit: forgot the default
    return total;
}



Log(Score); //19

编辑:我已经尝试过将条件转移到Select,但是这只会解决问题,即如何在Linq Select中添加条件?

public float Score => Colors.Select(x => 
{
    // The problem still happening
    if (x == Color.Red) {
        return 10.0f;
    } else if (x == Color.Yellow) {
        return 5.0f;
    } else if (x == Color.Green) {
        return 2.0f;
    }
    return 0.0f;
}
.Aggregate(0.0f, (total, next) => total + next);

这是一个复杂的示例,基本上它只是游戏的stat修饰符,

// This is a Game Status Modifier, for example: "Strength 30 + 10%"
public enum StatModType
{
    Flat = 100, // Flat addition to Stat
    PercentAdd = 200, // Percent addition to Stat
    ... // many other type of addition
}

private float _baseValue = 30.0f;

public List<StatModifier> StatModifiers = new List<StatModifier>
{...} //dummy data

public float Value => StatModifiers.Aggregate(_baseValue, (finalValue, mod) =>
{
    //I need help on this one
    if (mod.Type == StatModType.Flat)
        return finalValue + mod.Value;
    else if (mod.Type == StatModType.PercentAdd)
    // When we encounter a "PercentAdd" modifier
        return finalValue + finalValue * mod.Value;
    else if (mod.Type == ...)
        //and continues below everytime I add more modifier types..
}


Log(Value); // Strength = 33;

编辑:我只发布(信贷:https : //forum.unity.com/threads/tutorial-character-stats-aka-attributes-system.504095/)命令性代码,以防有人需要它,我也有一个很难读到这个:

private float CalculateFinalValue()
{
    float finalValue = BaseValue;
    float sumPercentAdd = 0; // This will hold the sum of our "PercentAdd" modifiers

    for (int i = 0; i < statModifiers.Count; i++)
    {
        StatModifier mod = statModifiers[i];

        if (mod.Type == StatModType.Flat)
        {
            finalValue += mod.Value;
        }
        else if (mod.Type == StatModType.PercentAdd) // When we encounter a "PercentAdd" modifier
        {
            sumPercentAdd += mod.Value; // Start adding together all modifiers of this type

            // If we're at the end of the list OR the next modifer isn't of this type
            if (i + 1 >= statModifiers.Count || statModifiers[i + 1].Type != StatModType.PercentAdd)
            {
                finalValue *= 1 + sumPercentAdd; // Multiply the sum with the "finalValue", like we do for "PercentMult" modifiers
                sumPercentAdd = 0; // Reset the sum back to 0
            }
        }
        else if (mod.Type == StatModType.PercentMult) // Percent renamed to PercentMult
        {
            finalValue *= 1 + mod.Value;
        }
    }

    return (float)Math.Round(finalValue, 4);
}

如何在聚合/缩小/扫描功能内添加条件?

德米特里·拜琴科(Dmitry Bychenko)

我建议在两种情况下都提取模型,即

简单的例子:

private static Dictionary<Color, float> s_ColorScores = new Dictionary<Color, float>() {
  {Color.Red,   10.0f},
  {Color.Yellow, 5.0f},
  {Color.Green,  2.0f},
};

...

float Score = Colors
  .Sum(color => s_ColorScores[color]);

复杂的例子:

private static Dictionary<StatModType, Func<float, float, float>> s_Modifications = new 
  Dictionary<StatModType, Func<float, float, float>> {
    {StatModType.Flat,       (prior, value) => prior + value},
    {StatModType.PercentAdd, (prior, value) => prior + prior * value},
     //TODO: add modification rules here
  };

public float Value => StatModifiers
  .Aggregate(_baseValue, (prior, mod) => s_Modifications[mod.Type](prior, mod.Value));

因此,您将拥有带有规则,设置,余额等(您可能希望对其进行调整,也许得分更高)的游戏模型s_ColorScoress_Modifications...),并将其与简单的业务逻辑分开Color.Yellow6.0f

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章