确定数字是否在指定的范围集内
我正在寻找一种流畅的方法来确定一个数字是否在指定的范围内。 我当前的代码看起来像这样:
int x = 500; // Could be any number if ( ( x > 4199 && x 6999 && x 9999 && x 10999 && x 11999 && x < 12100 ) ) { // More awesome code }
有更好的方法吗?
扩展方法?
bool Between(this int value, int left, int right) { return value > left && value < right; } if(x.Between(4199, 6800) || x.Between(6999, 8200) || ...)
你也可以做这个糟糕的黑客:
bool Between(this int value, params int[] values) { // Should be even number of items Debug.Assert(values.Length % 2 == 0); for(int i = 0; i < values.Length; i += 2) if(!value.Between(values[i], values[i + 1]) return false; return true; } if(x.Between(4199, 6800, 6999, 8200, ...)
糟糕的黑客,改进:
class Range { int Left { get; set; } int Right { get; set; } // Constructors, etc. } Range R(int left, int right) { return new Range(left, right) } bool Between(this int value, params Range[] ranges) { for(int i = 0; i < ranges.Length; ++i) if(value > ranges[i].Left && value < ranges[i].Right) return true; return false; } if(x.Between(R(4199, 6800), R(6999, 8200), ...))
或者,更好(这不允许重复的下限):
bool Between(this int value, Dictionary ranges) { // Basically iterate over Key-Value pairs and check if value falls within that range } if(x.Between({ { 4199, 6800 }, { 6999, 8200 }, ... }
定义Range类型,然后创建一组范围和扩展方法,以查看值是否位于任何范围内。 然后,您可以创建范围的集合,也可以创建一些单独的范围,而不是硬编码值,为它们提供有用的名称来解释您对它们感兴趣的原因 :
static readonly Range InvalidUser = new Range(100, 200); static readonly Range MilkTooHot = new Range (300, 400); static readonly IEnumerable Errors = new List { InvalidUser, MilkTooHot }; ... // Normal LINQ (where Range defines a Contains method) if (Errors.Any(range => range.Contains(statusCode)) // or (extension method on int) if (statusCode.InAny(Errors)) // or (extension methods on IEnumerable ) if (Errors.Any(statusCode))
您可能对作为MiscUtil一部分的通用Range
类型感兴趣。 它允许以简单的方式迭代:
foreach (DateTime date in 19.June(1976).To(25.December(2005)).Step(1.Days())) { // etc }
(显然,这也使用了一些与DateTime / TimeSpan相关的扩展方法,但你明白了。)
我个人更喜欢@Anton建议的扩展方法 – 但是如果你不能这样做,并且会坚持你当前的代码,我认为你可以通过颠倒每行的第一组条件使其更具可读性,如下所示…
int x = 500; // Could be any number if ( ( 4199 < x && x < 6800 ) || ( 6999 < x && x < 8200 ) || ( 9999 < x && x < 10100 ) || ( 10999 < x && x < 11100 ) || ( 11999 < x && x < 12100 ) ) { // More awesome code }
LINQ方法:
添加参考:
using System.Linq; /// /// Test to see if value is in specified range. /// /// int /// int /// int /// bool public static bool CheckValueInRange(int aStart, int aEnd, int aValueToTest) { // check value in range... bool ValueInRange = Enumerable.Range(aStart, aEnd).Contains(aValueToTest); // return value... return ValueInRange; }
class Range { public Range(int x, int y) { X = x; Y = y; } public int X { get; set; } public int Y { get; set; } } var ranges = new List(); ranges.Add(new Range(4199,6800)); ranges.Add(new Range(6999,8200)); ranges.Add(new Range(9999,10100)); ranges.Add(new Range(10999,11100)); ranges.Add(new Range(11999,12100)); bool inRange = ranges.Count(r => x >= rX && x <= rY) > 0; //or -- Based on Jons recommendation bool inRange = ranges.Any(r => x >= rX && x <= rY);
如果你需要在某个时刻遍历值对,我建议你捕获最大的较低值和最小的上限值,就像你做变量一样:
if ( x>max_lower && x
尝试以下方法:
struct Range { public readonly int LowerBound; public readonly int UpperBound; public Range( int lower, int upper ) { LowerBound = lower; UpperBound = upper; } public bool IsBetween( int value ) { return value >= LowerBound && value <= UpperBound; } } public void YourMethod( int someValue ) { List ranges = {new Range(4199,6800),new Range(6999,8200), new Range(9999,10100),new Range(10999,11100), new Range(11999,12100)}; if( ranges.Any( x => x.IsBetween( someValue ) ) { // your awesome code... } }
在Pascal(Delphi)中,您有以下声明:
if x in [40..80] then begin end
因此,如果值x落在该范围内,则执行命令。 我正在寻找与此相当的C#,但找不到像这样简单和“优雅”的东西。
这个if in()then语句接受字符串,字节等。