C#中是否存在“介于”函数?


74

Google不了解“间”是我要查找的函数的名称,并且不返回任何相关内容。

例如:我只想检查一次操作中5是否在0到10之间


2
在某种程度上做这件事在数学上是不可能的...您是否尝试过自己编写?
AK_11年

3
.NET库并非在阳光下具有所有功能。您仍然必须自己编写一些代码;)
拜伦·惠特洛克

2
我很好奇SQL也有一个BETWEEN运算符,请检查一下,乔恩做了一个等效的LINQ stackoverflow.com/questions/1447635/linq-between-operator
Tom

1
...也没有功能...:-/
Peter C

MySql但没有c#
Ismail Gunes

Answers:


93

不,但是您可以编写自己的:

public static bool Between(this int num, int lower, int upper, bool inclusive = false)
{
    return inclusive
        ? lower <= num && num <= upper
        : lower < num && num < upper;
}

3
这可能很有用,但是Lambda表达式不允许具有可选参数的成员。我会去超载;-)
dandel

10
那不是lambda。小于或等于。
约翰·罗德

130

不清楚“一个操作”是什么意思,但是不,我不知道确定某个项目是否在范围内的运算符/框架方法。

您当然可以自己编写扩展方法。例如,这里假设间隔在两个端点上都是闭合的

public static bool IsBetween<T>(this T item, T start, T end)
{
    return Comparer<T>.Default.Compare(item, start) >= 0
        && Comparer<T>.Default.Compare(item, end) <= 0;
}

然后将其用作:

bool b = 5.IsBetween(0, 10); // true

对于未实现IComparable<T>或的类型,这将如何表现IComparable
山姆

13
@Sam它会引发异常,但是要避免这种情况,您可以添加where T : IComparable, IComparable<T>
WiiMaxx 2013年

这应该是公认的解决方案;添加一个“包含”参数也很容易。
System.Cats.Lol 2014年

1
很好,但是如果您不需要这个包容性,并且您希望3介于5和2之间(以及2和5之间),请使用:return Comparer<T>.Default.Compare(item, start) == -Comparer<T>.Default.Compare(item, end);
mathieu

32

这是一堂完整的课。

/// <summary>
/// An extension class for the between operation
/// name pattern IsBetweenXX where X = I -> Inclusive, X = E -> Exclusive
/// <a href="https://stackoverflow.com/a/13470099/37055"></a>
/// </summary>
public static class BetweenExtensions
{

    /// <summary>
    /// Between check <![CDATA[min <= value <= max]]> 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">the value to check</param>
    /// <param name="min">Inclusive minimum border</param>
    /// <param name="max">Inclusive maximum border</param>
    /// <returns>return true if the value is between the min & max else false</returns>
    public static bool IsBetweenII<T>(this T value, T min, T max) where T:IComparable<T>
    {
        return (min.CompareTo(value) <= 0) && (value.CompareTo(max) <= 0);
    }

    /// <summary>
    /// Between check <![CDATA[min < value <= max]]>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">the value to check</param>
    /// <param name="min">Exclusive minimum border</param>
    /// <param name="max">Inclusive maximum border</param>
    /// <returns>return true if the value is between the min & max else false</returns>
    public static bool IsBetweenEI<T>(this T value, T min, T max) where T:IComparable<T>
    {
        return (min.CompareTo(value) < 0) && (value.CompareTo(max) <= 0);
    }

    /// <summary>
    /// between check <![CDATA[min <= value < max]]>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">the value to check</param>
    /// <param name="min">Inclusive minimum border</param>
    /// <param name="max">Exclusive maximum border</param>
    /// <returns>return true if the value is between the min & max else false</returns>
    public static bool IsBetweenIE<T>(this T value, T min, T max) where T:IComparable<T>
    {
        return (min.CompareTo(value) <= 0) && (value.CompareTo(max) < 0);
    }

    /// <summary>
    /// between check <![CDATA[min < value < max]]>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">the value to check</param>
    /// <param name="min">Exclusive minimum border</param>
    /// <param name="max">Exclusive maximum border</param>
    /// <returns>return true if the value is between the min & max else false</returns>

    public static bool IsBetweenEE<T>(this T value, T min, T max) where T:IComparable<T>
    {
        return (min.CompareTo(value) < 0) && (value.CompareTo(max) < 0);
    }
}

加上一些单元测试代码

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethodIsBeetween()
    {
        Assert.IsTrue(5.0.IsBetweenII(5.0, 5.0));
        Assert.IsFalse(5.0.IsBetweenEI(5.0, 5.0));
        Assert.IsFalse(5.0.IsBetweenIE(5.0, 5.0));
        Assert.IsFalse(5.0.IsBetweenEE(5.0, 5.0));

        Assert.IsTrue(5.0.IsBetweenII(4.9, 5.0));
        Assert.IsTrue(5.0.IsBetweenEI(4.9, 5.0));
        Assert.IsFalse(5.0.IsBetweenIE(4.9, 5.0));
        Assert.IsFalse(5.0.IsBetweenEE(4.9, 5.0));

        Assert.IsTrue(5.0.IsBetweenII(5.0, 5.1));
        Assert.IsFalse(5.0.IsBetweenEI(5.0, 5.1));
        Assert.IsTrue(5.0.IsBetweenIE(5.0, 5.1));
        Assert.IsFalse(5.0.IsBetweenEE(5.0, 5.1));

        Assert.IsTrue(5.0.IsBetweenII(4.9, 5.1));
        Assert.IsTrue(5.0.IsBetweenEI(4.9, 5.1));
        Assert.IsTrue(5.0.IsBetweenIE(4.9, 5.1));
        Assert.IsTrue(5.0.IsBetweenEE(4.9, 5.1));

        Assert.IsFalse(5.0.IsBetweenII(5.1, 4.9));
        Assert.IsFalse(5.0.IsBetweenEI(5.1, 4.9));
        Assert.IsFalse(5.0.IsBetweenIE(5.1, 4.9));
        Assert.IsFalse(5.0.IsBetweenEE(5.1, 4.9));

    }
}

7
T应该是IComparable <T>而不是IComparable,否则您将获得拳击
Mark Sowul

22

不,您必须分别测试每个端点。

if ((x > 0) && (x < 10)) {
   // do stuff
}

或者,如果您希望它看起来更“中间”,请对args重新排序:

if ((0 < x) && (x < 10)) {
   // do stuff
}

16

到目前为止,似乎没有一个答案考虑到动态地存在的可能性,您不知道哪个值是上下限。对于一般情况,您可以创建自己的IsBetween方法,该方法可能类似于:

    public bool IsBetween(double testValue, double bound1, double bound2)
    {
        return (testValue >= Math.Min(bound1,bound2) && testValue <= Math.Max(bound1,bound2));
    }

11

C#/。NET中没有内置的构造,但是您可以为此轻松添加自己的扩展方法:

public static class ExtensionsForInt32
{
    public static bool IsBetween (this int val, int low, int high)
    {
           return val > low && val < high;
    }
}

可以这样使用:

if (5.IsBetween (0, 10)) { /* Do something */ }

+1。唯一需要警告的是,要使消费者期望边缘情况(0和10)不包含在内。否则,这太棒了!
p.campbell

我将这种方法与Ani提出的方法结合使用。我将IsBetween函数作为私有成员添加到了扩展类中。然后,我使用类似于此的公共函数来公开我想要扩展的特定类型,这些特定类型调用私有函数。
JRodd

5

在编译时经过验证的通用函数!

public static bool IsBetween<T>(this T item, T start, T end) where T : IComparable
{
    return item.CompareTo(start) >= 0 && item.CompareTo(end) <= 0;
}

4

除了@Ed G的答案外,所有答案都需要知道哪个界限是下限,哪个是上限。

当您不知道哪个边界是哪个时,这是一种(相当不明显)的方法。

  /// <summary>
  /// Method to test if a value is "between" two other values, when the relative magnitude of 
  /// the two other values is not known, i.e., number1 may be larger or smaller than number2. 
  /// The range is considered to be inclusive of the lower value and exclusive of the upper 
  /// value, irrespective of which parameter (number1 or number2) is the lower or upper value. 
  /// This implies that if number1 equals number2 then the result is always false.
  /// 
  /// This was extracted from a larger function that tests if a point is in a polygon:
  /// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
  /// </summary>
  /// <param name="testValue">value to be tested for being "between" the other two numbers</param>
  /// <param name="number1">one end of the range</param>
  /// <param name="number2">the other end of the range</param>
  /// <returns>true if testValue >= lower of the two numbers and less than upper of the two numbers,
  ///          false otherwise, incl. if number1 == number2</returns>
  private static bool IsInRange(T testValue, T number1, T number2)
  {
     return (testValue <= number1) != (testValue <= number2);
  }

注意:这不是通用方法;它是伪代码。上述方法中的T应该用适当的类型“ int”或“ float”或其他任何类型替换。(有很多方法可以使这种通用,但是它们很混乱,以至于单行方法是不值得的,至少在大多数情况下不是这样。)


2
程序员曾经这样理解逻辑:)
Fattie 2015年

我意识到这在Internet时代是“古老的”,但是我真的很喜欢这种解决方案,特别是因为它不需要调用方知道哪个边界是哪个。
安德鲁·斯蒂兹

4

会不会像

0 < 5 && 5 < 10

因此,我想如果您想要一个函数,可以简单地将其添加到实用程序类中:

public static bool Between(int num, int min, int max) {
    return min < num && num < max;
}

我期望像bool x = Math.between(5,0,10)之类的东西,但我猜它不存在,所以我必须坚持大/小符号
Mathieu

好吧,您可以使用我想的扩展方法。
彼得·C

Wadda知道,请查看Pete的答案。
彼得C

返回类型应该bool不是void
伊曼纽尔·文提尔(EmanuelVintilă)

3
int val_to_check = 5
bool in_range = Enumerable.Range(0, 13).Contains(val_to_check);

第二个参数是“计数”,而不是结束数或高位数。

IE浏览器

int low_num = 0
int high_num = 12
int val_to_check = 5
bool in_range = Enumerable.Range(low_num , high_num - low_num + 1).Contains(val_to_check);

检查val_to_check是否在0到12之间


3

请参考此链接。这个问题的一线解决方案。

如何优雅地检查数字是否在范围内?

int x = 30;
if (Enumerable.Range(1,100).Contains(x))
//true

if (x >= 1 && x <= 100)
//true

我知道该职位已经很老了,但可能会对其他人有所帮助。


1
如果此问题与您在此处链接的问题重复,请在问题下方用“标志”按钮将其标记为重复,而不要为此留一个答案。如果不是重复的,请留下完整的答案,而不是仅链接的答案。
josliber

2

关于什么

somenumber == Math.Max(0,Math.Min(10,somenumber));

当somenumber为5时返回true。当somenumber为11时返回false。


1

正如@Hellfrost指出的那样,在“一个操作”中将一个数字与两个不同的数字进行比较在字面上是胡说八道,而且我知道没有C#运算符对此进行封装。

between = (0 < 5 && 5 < 10);

是我能想到的最紧凑的形式。

您可以使用扩展程序制作一种看上去“流利”的方法(尽管虽然有趣,但我认为这太过分了):

public static bool Between(this int x, int a, int b)
{
    return (a < x) && (x < b);
}

采用:

int x = 5;
bool b = x.Between(0,10);

因此,这在c#中不存在,我确定可以确定这是python本身支持的
Davide Piras,

那是因为电池与C#分开出售。;)
Peter C

0

我不知道那个功能;无论如何,如果您的值是无符号的,则只有一个操作意味着(val <11)...如果是有符号的,我认为没有原子的方法可以做到,因为10并非2的幂。


0

Base @Dan J这个版本不在乎max / min,更像sql :)

public static bool IsBetween(this decimal me, decimal a, decimal b, bool include = true)
{
    var left = Math.Min(a, b);
    var righ = Math.Max(a, b);

    return include
        ? (me >= left && me <= righ)
        : (me > left && me < righ)
    ;
}

0

或者,如果您想将值绑定到间隔:

public static T EnsureRange<T>(this T value, T min, T max) where T : IComparable<T>
    {
        if (value.CompareTo(min) < 0)
            return min;
        else if (value.CompareTo(max) > 0)
            return max;
        else
            return value;
    }

就像双面Math.Min / Max


0

对于负值:

    Public Function IsBetween(Of T)(item As T, pStart As T, pEnd As T) As Boolean ' https://msdn.microsoft.com/fr-fr/library/bb384936.aspx
    Dim Deb As T = pStart
    Dim Fin As T = pEnd
    If (Comparer(Of T).Default.Compare(pStart, pEnd) > 0) Then Deb = pEnd : Fin = pStart
    Return Comparer(Of T).Default.Compare(item, Deb) >= 0 AndAlso Comparer(Of T).Default.Compare(item, Fin) <= 0
End Function
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.