简体   繁体   English

查找范围内值的最佳方法

[英]Best way to find values in range

I have a collection of values: 我有一些价值观:

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

I expect input from users in the for of [44] for example. 例如,我希望用户输入[44]中的。 What would be the most eloquent way to determine in which item the value falls? 确定该值属于哪一项的最雄辩的方法是什么?

I can write a switch statement to match a case > < or an if...statement but neither of these in my opinion is eloquent enough. 我可以编写一个switch语句来匹配一个case> <或一个if ...语句,但是我认为这两个都不是很能说明问题。

Update 更新资料

I'm looking for a neat and tidy way of finding the range in which my user's input fall, using something like LAMDBA for example: 我正在寻找一种整洁的方法来查找用户输入范围,例如使用LAMDBA之类的方法:

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

Or something like that. 或类似的东西。

Something like this as an extension: 像这样的扩展:

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

without if statements 没有if语句

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

usage: 用法:

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

If your ranges are consecutive, as in your example (ie there are no gaps), you can store their endpoints in an array, like this: 如果您的范围是连续的,例如您的示例(即没有间隙),则可以将它们的端点存储在数组中,如下所示:

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

Note that the endpoints are sorted. 请注意,端点已排序。 You can now use a binary search method to find the insertion point of 44 in this array, which is 3, will be returned (binary search will return bitwise complement of 3; you'd need to apply ~ to get the actual value). 现在,您可以使用二进制搜索方法在该数组中找到插入点44,该插入点将返回3(二进制搜索将返回3的按位补码;您需要应用~以获取实际值)。

There you go: 你去了:

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

No ifs! 不,如果!

Just loop over the ranges and see if the value falls within the range... 只需循环遍历范围,看看该值是否在范围内...

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
    }
}

You could just manipulate the inputs: 您可以操纵输入:

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

Assuming integer input, and that your array is indexed as indicated. 假设输入为整数,并且您的数组已按指示建立索引。

UPDATE : I know this is an overkill but it might give you some ideas. 更新 :我知道这太过分了,但可能会给您一些想法。 As I undestand, you already know how to solve this problem, but you are just looking for a "prettier" solution: 我不理解,您已经知道如何解决此问题,但是您只是在寻找“更漂亮”的解决方案:

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);
}

My previous suggestion : For statement is ok but I prefer LINQ :) 我以前的建议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);

Less efficient .NET 3.5 alternative variation of @Jeff Mercado's answer: @Jeff Mercado的答案效率较低的.NET 3.5替代版本:

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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM