如何在数字范围的函数中优雅地赋值?

时间:2013-08-14 15:09:09

标签: c# numbers range

我正在寻找一种优雅的方法来为属于特定范围的数字赋值。

例如,如果数字为X,elegant way将返回:

  • 'a' - 如果X介于0和1000之间
  • 'b' - 如果X介于1000和1500之间
  • 等等(但定义的间隔数量固定)

优雅我指的是比

更吸引人的东西
if ((x => interval_1) && (x < interval_2))
    class_of_x = 'a';
else if ((x => interval_2) && (x < interval_3))
    class_of_x = 'b';
...

if(Enumerable.Range(interval_1, interval_2).Contains(x))
    class_of_x = 'a';
else if(Enumerable.Range(interval_2 + 1, interval_3).Contains(x))
    class_of_x = 'b';
...

我讨厌看到这么多的IF。 此外,间隔值可以存储在一个集合中(这可能会帮助我消除IS?),而不必作为interval_1,interval_2等等。

在寻找上述问题的解决方案时出现的问题How to elegantly check if a number is within a range?引起了一些启发。

5 个答案:

答案 0 :(得分:1)

如果我的评论是正确的,那么你的第一个if语句有很多不必要的检查,如果它不小于2,那么它必须大于或等于,因此:

if((x => i1) && (x < i2))
else if(x < i3)
else if(x < i4)...

如果找到“真实”参数,则if语句的其余部分无关紧要,只要您的条件符合您的需求

答案 1 :(得分:1)

您可以创建扩展方法:

public static class IntExtensions
{
    // min inclusive, max exclusive
    public static bool IsBetween(this int source, int min, int max)
    {
        return source >= min && source < max
    }
}

然后

// Item1 = min, Item2 = max, Item3 = character class
IList<Tuple<int, int, char>> ranges = new List<Tuple<int, int, char>>();
// init your ranges here
int num = 1;
// assuming that there certainly is a range which fits num,
// otherwise use "OrDefault"
// it may be good to create wrapper for Tuple, 
// or create separate class for your data
char characterClass = ranges.
                        First(i => num.IsBetween(i.Item1, i.Item2)).Item3;

答案 2 :(得分:1)

首先,定义一个小类来保存包含的最大值,以及用于该波段的相应值:

sealed class Band
{
    public int  InclusiveMax;
    public char Value;
}

然后声明一个Band数组,它指定用于每个band和loop的值,以找到任何输入的相应band值:

public char GetSetting(int input)
{
    var bands = new[]
    {
        new Band {InclusiveMax = 1000, Value = 'a'},
        new Band {InclusiveMax = 1500, Value = 'b'},
        new Band {InclusiveMax = 3000, Value = 'c'}
    };

    char maxSetting = 'd';

    foreach (var band in bands)
        if (input <= band.InclusiveMax)
            return band.Value;

    return maxSetting;
}

注意:在实际代码中,您可以将所有这些包装到一个只初始化bands数组的类中,而不是每次调用它(就像在上面的代码中一样)。

答案 3 :(得分:1)

创建一个Interval类并使用LINQ:

public class Interval
{
    public string TheValue { get; set; }
    public int Start { get; set; }
    public int End { get; set; }

    public bool InRange(int x)
    {
        return x >= this.Start && x <= this.End;
    }
}

public void MyMethod()
{
    var intervals = new List<Interval>();

    // Add them here...

    var x = 3213;
    var correctOne = intervals.FirstOrDefault(i => i.InRange(x));

    Console.WriteLine(correctOne.TheValue);
}

答案 4 :(得分:0)

在这里你也可以使用静态的System.Linq.Enumerable实现的Range()方法

IEnumerable<T>

使用Contains()方法(再次来自System.Linq.Enumerable),做类似的事情:

var num = 254;
if(Enumerable.Range(100,300).Contains(num)) { ...your logic here; }

至少在我看来,这看起来更优雅。