2010-01-14 24 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

相關問題