2010-01-14 21 views
5

自从我开始编程适当的编程用好老VB6和直到今天,我还经常会烫伤(和只)本:“或”操作,而无需重复左手条件再次

if x == something or x == somethingelse 

我经常写出来:

if x == something or somethingelse 

只是出于纯粹的兴趣,是否有任何的langauge /语言在那里支持呢?

回答

11

Python做,那种:

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

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

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

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

+0

这是一种欺骗;)你也可以在.NET中使用IList + LINQ来做到这一点。 –

+0

这不是作弊,这是你做这件事的方式。你左边的东西是免费的! – Thomas

+0

接受,虽然如前所述,它有点作弊,并需要一个列表,而不是在语言构造中直接实现。 – Finglas

3

在很多编程语言中,你可以做这样的事情:

myArray[something, somethingElse].Contains(x) 

...但我的猜测是,它会执行略差。

+0

我的快速测试显示,在python中,“if x == 3或x == 5”和“if in [3,5]”中的性能几乎完全相同。但是,我毫不怀疑测试可能更加完整和确凿。 – Cdsboy

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

在语言中有 “开关” 操作,你可以这样做:

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

    default: 
    { 
     // else case 
     break;  
    } 
} 

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

+0

假设'x'是可以开启的类型。在C语言和大多数C语言中,这只适用于整数。 – Thomas

+0

如果'x'不是可以“切换”的东西,那么可能没有优化。对于字符串列表,您需要在每个字符串上调用'strcmp()'或等价物,或者使用'for'循环。 –

0

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

1

MATLAB有几个方法来处理第二种形式你上面所列内容:

if any(x == [something somethingelse]) ... 
%# OR 
if ismember(x,[something somethingelse]) ... 
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). 

所以的情况下,我们可以使用可变参数,功能在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; 
} 

可变参数允许定义一个单一的功能,取入的参数个数可变,使得可以使用相同的方法来比较

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

然而,上述用于字符串比较只限定,所以我们必须为每个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++中,我从来没有尝试操作可变参数重载甚至不知道它是否是可能的。

再访: 然而,重温这一小时后,

我们可以定义一个类

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

我们可以扩大它,我们可以做inany,inall,gtany,gtall,ltany,ltall等通过扩大co比较功能。

2

Icon programming language支持这个成语很漂亮。Icon是由Ralph Griswold设计的,他已经设计了SNOBOL,它的整个评估模型建立在成功或失败之上。一切都构成了,原则上每个表达式都可以产生多重结果。你可以写这样的事情

if x == (something | somethingelse) then write("Goodie!") 

这里的评价模型:

  1. 首先您评估括号中的表达,并得到something
  2. 那么你应该比较somethingx
  3. 如果他们不等于,表达式失败,并且评估引擎自动回溯。
  4. 在回溯期间,对括号内表达式的评估是恢复,并且它再次成功!这一次它产生somethingelse
  5. 让我们假设这个比较成功。然后对if的主体进行评估,并将程序写入标准输出。

以下是另一个有趣的场景:每个比较要么成功要么失败,如果成功,则返回其右手参数。所以,你可以做的界限与

lo <= x < limit 

这个表达式检查正是如此parenthesizes:

(lo <= x) < limit 

所以,如果lox越大,括号表达式失败,所以整个事情失败。 (如果它的任何部分失败,则普通表达式失败。)但是,如果lo最多为x,则lo <= x成功并返回x。当然,下一步,机器比较x < limit,如果成功,整个事情就成功了。

图标是一种非常一致的语言,非常易于使用,并且未被重视。但是它并没有很好地与操作系统整合在一起,并且当他们有一个和Unix一起使用的版本时,Icon已经失去了获得思想共享的机会。但是所有的语言设计师都可以通过学习来学习。

R.I.P.

+0

有趣的是,我从来没有听说过它。 – Finglas

相关问题