查找范围内值的最佳方法

时间:2012-02-02 14:25:04

标签: c#

我有一组价值观:

  • [0-20] = 1
  • [21-30] = 2
  • [31-40] = 3等。

我希望用户的输入例如[44]。什么是最有说服力的方法来确定价值落在哪个项目?

我可以编写一个switch语句来匹配case> <或者if ...声明,但我认为这些都不够雄辩。

更新

我正在寻找一种干净利落的方法来找到用户输入的范围,例如LAMDBA:

List<int>().Find(x => x.WithinRange(range))

或类似的东西。

7 个答案:

答案 0 :(得分:4)

像这样的扩展名:

public static int WithinRange(this int value)
{
    if (value < 0) return 0;
    if (value < 21) return 1;
    return (value - 1) / 10;
}

没有if语句

public static int WithinRange(this int value)
{
    return (value < 0) ? 0 
        : (value < 21) ? 1 
        : (value - 1) / 10;
}

用法:

collection.Find(x => x.WithinRange(range)) 

答案 1 :(得分:4)

如果您的范围是连续的,如您的示例所示(即没有间隙),您可以将其端点存储在数组中,如下所示:

var endpoints = new[] {20, 30, 40, 60, 90};

请注意,端点已排序。您现在可以使用binary search方法在此数组中找到44的插入点,即3,将返回(二进制搜索将返回3的按位补码;您需要应用~得到实际值。)

答案 2 :(得分:4)

你去了:

int GetRange(int value) 
{ 
    return (value > 30) ? 3 :
           (value > 20) ? 2 :
           (value > 0)  ? 1 :
           0;
}

不,如果!

答案 3 :(得分:2)

只需遍历范围并查看该值是否在范围内......

var ranges = new[]
{
    Tuple.Create(0, 20),
    Tuple.Create(21, 30),
    Tuple.Create(31, 40),
    Tuple.Create(41, 50),
    // ...
};
var number = 44;
for (int i = 0; i < ranges.Length; i++)
{
    var range = ranges[i];
    if (number >= range.Item1 && number <= range.Item2)
    {
        var theIndex = i + 1;
        // do something with theIndex
    }
}

答案 4 :(得分:1)

你可以操纵输入:

int input = //Whatever the input is
int index = (input-1)/10;

假设整数输入,并且您的数组按指示索引。

答案 5 :(得分:0)

更新:我知道这是一种矫枉过正,但它可能会给你一些想法。正如我所说,你已经知道如何解决这个问题,但你只是在寻找一个“更漂亮”的解决方案:

public class Range
{
    public int Left { get; set; }   
    public int Right { get; set; }
    public string Title { get; set; }

    public Range(int left, int right, string title) { Left = left; Right = right; Title = title; }

    public bool Contains(int x) { return Left <= x && x <= Right; }
}

void Main()
{
    var x = 15;

    var ranges = new[] {
        new Range(0, 10, "A"),
        new Range(11, 20, "B")
    };

    var foo = ranges.Where(r => r.Contains(x)).Single();

    Console.Write(foo.Title);
}

我之前的建议For声明没问题,但我更喜欢LINQ:)

var x = 15;

var ranges = new[] { Tuple.Create(0, 10), Tuple.Create(11, 20) };
var range = ranges.Where(r => r.Item1 <= x && r.Item2 >= x );

Console.Write(range.Item1);
Console.Write(range.Item2);

答案 6 :(得分:0)

效率较低的.NET 3.5替代变体@Jeff Mercado的回答:

var ranges = new[]
{
    Enumerable.Range(0, 20),
    Enumerable.Range(21, 30),
    Enumerable.Range(31, 40),
    Enumerable.Range(41, 50),
    // ...
};
var number = 44;
for (int i = 0; i < ranges.Length; i++)
{
    var range = ranges[i];
    if (range.Contains(number))
    {
        var theIndex = i + 1;
        // do something with theIndex
    }
}