“或”运算符不再重复左手条件

时间:2010-01-14 18:17:48

标签: programming-languages operators

自从我开始使用好的VB6并且直到今天开始编程时,我经常在编程中被烧毁(并且只是):

if x == something or x == somethingelse

我经常写作:

if x == something or somethingelse

出于纯粹的兴趣,那里的语言/语言是否支持这个?

8 个答案:

答案 0 :(得分:11)

Python确实如此:

if x in [something, somethingelse]:
    ...

in只检查元素是否出现在给定列表中。同样,在Haskell中:

if x `elem` [something, somethingelse] then ...

我认为这可以在大多数允许列表类型表达的语言中完成。

答案 1 :(得分:6)

SQL有一个in运算符:x in (something, somethingelse),有许多语言可以实现类似的东西。

例如,在c#中,我使用自定义扩展方法:if (x.In("something", "somethingelse"))...

编辑这是我的c#扩展方法的来源:

public static bool In<T>(this T item, params T[] test_values) {
  foreach (T test_value in test_values)
  {
    if (test_value.Equals(item))
    {
      return true;
    }
  }

  return false;
}

答案 2 :(得分:3)

在许多编程语言中,您可以执行以下操作:

myArray[something, somethingElse].Contains(x)

......但我猜他的表现会稍差一些。

答案 3 :(得分:2)

Icon programming language精美地支持这个习语。 Icon由已经设计过SNOBOL的Ralph Griswold设计,它的整体评估模型建立在成功或失败的基础之上。一切都在构成,原则上每个表达都可以产生多种结果。你可以写

之类的东西
if x == (something | somethingelse) then write("Goodie!")

以下是评估模型:

  1. 首先,您在括号中评估表达式并获取something
  2. 然后您将somethingx
  3. 进行比较
  4. 如果它们不相等,表达式将失败,评估引擎会自动回溯。
  5. 在回溯期间,括号表达式的评估已恢复,并且它再次成功!这次它产生somethingelse
  6. 我们假设这种比较成功了。然后评估if的主体,程序写入标准输出。
  7. 这是另一个有趣的场景:每次比较要么成功要么失败,如果成功,它会返回右手参数。所以你可以用

    进行边界检查
    lo <= x < limit
    

    这个表达式因此括起来:

    (lo <= x) < limit
    

    因此,如果lo大于x,括号表达式将失败,因此整个过程失败。 (如果普通表达式的任何部分失败,则表示失败。)但如果lo最多为x,则lo <= x 成功并返回x 。接下来当然,机器会比较x < limit,如果成功,整个过程就会成功。

    Icon是一种非常一致的语言,非常易于使用,并且被低估了。但它从未与操作系统很好地集成,当他们拥有一个与Unix配合良好的版本时,Icon已经失去了获得思想共享的机会。但是所有语言设计师都可以通过研究来学到很多东西。

    R.I.P。

答案 4 :(得分:1)

在使用“switch”操作符的语言中,您可以执行以下操作:

switch (x)
{
    case 1:
    case 2:
    {
      // do whatever
      break;
    }

    default:
    {
        // else case
        break;       
    }
}

它有点冗长,但在C中你可以将其隐藏在宏或C ++中,也许是模板。

答案 5 :(得分:1)

MATLAB有几种方法可以处理上面列出的第二种形式:

if any(x == [something somethingelse]) ...
%# OR
if ismember(x,[something somethingelse]) ...

答案 6 :(得分:0)

Perl:$foo ~~ ['string',$number,qr/regex/]

答案 7 :(得分:0)

如果

A in [x, y, z]

被认为是有效的解决方案,然后是函数

in(A, x, y, z)

也应被视为有效的解决方案,特别是对于允许运算符重载的语言,以便cmp(A,x,y,z)可以映射到

A in x y z

到目前为止的讨论已经讨论了

if (A == x or y or z).

的情况怎么样?
if (A == x and y and z).

因此,我们将使用varargs,这是c,c ++,c#和java5中的一个特性。

让我们用java来说明。

boolean or(String lhs, String... rhs){
  for(String z: rhs){
    if (lhs.equals(z) return true;
  }
  return false;
}

boolean and(String lhs, String... rhs){
  for(String z: rhs){
    if (!lhs.equals(z) return false;
  }
  return true;
}

Varargs允许您定义一个接受可变数量参数的单个函数,以便您可以使用相同的方法进行比较

or (A, x)
or (A, x, y)
or (A, x, y, z)

但是,上面只定义了String比较,因此我们必须为每个arg类型创建一对方法。但是在Java 5中有泛型。

<T extends Comparable<T>>boolean or(T lhs, T... rhs){
  for(T z: rhs){
    if (lhs.compareTo(z)==0) return true;
  }
  return false;
}

<T extends Comparable<T>>boolean and(T lhs, T... rhs){
  for(T z: rhs){
    if (lhs.compareTo(z)!=0) return false;
  }
  return true;
}

现在,您可以对实现类似接口的任何类型进行比较。

and(stringA, stringx, stringy)
or(dateA, datex)

太糟糕了,Java不允许运算符重载,所以我们可以做

stringA && stringx, stringy
dateA || datex, datey, datez

在c ++中,我从未尝试使用varargs进行运算符重载甚至知道是否可能。

<强>重温: 但是,稍后重新访问,

我们可以定义一个类

public class <T extends Comparable<T>> Comparigator{
  public Comparigator(T lhs){
    this.lhs = lhs;
  }
  final private T lhs;

  static public <T extends Comparable<T>> Comparigator is(T lhs){
    return (T)new Comparigator(lhs);
  }

  public boolean inAny(T... rhs){
    for(T z: rhs){
      if (this.lhs.compareTo(z)==0) return true;
    }
    return false;
  }

  public boolean inAll(T... rhs){
    for(T z: rhs){
      if (this.lhs.compareTo(z)!=0) return false;
    }
    return true;
  }

  public boolean gtAny(T... rhs){
    for(T z: rhs){
      if (this.lhs.compareTo(z)>0) return true;
    }
    return false;
  }

  public boolean gtAll(T... rhs){
    for(T z: rhs){
      if (this.lhs.compareTo(z)<=0) return false;
    }
    return true;
  }
}

现在,我们根本不需要运算符重载,我们可以做

import Comparigator;
.....

is(A).inAny(x,y,z); // or
is(A).inAll(w,x,y,z); // and

is(B).gtAny(k,l,m);
is(C).gtAll(j,k);

我们可以扩展它,我们可以通过扩展比较功能来实现inall,gtany,gtall,ltany,ltall等。