自從我開始編程適當的編程用好老VB6
和直到今天,我還經常會燙傷(和只)本:「或」操作,而無需重複左手條件再次
if x == something or x == somethingelse
我經常寫出來:
if x == something or somethingelse
只是出於純粹的興趣,是否有任何的langauge /語言在那裏支持呢?
自從我開始編程適當的編程用好老VB6
和直到今天,我還經常會燙傷(和只)本:「或」操作,而無需重複左手條件再次
if x == something or x == somethingelse
我經常寫出來:
if x == something or somethingelse
只是出於純粹的興趣,是否有任何的langauge /語言在那裏支持呢?
Python做,那種:
if x in [something, somethingelse]:
...
in
只檢查是否在給定的列表中出現的元素。同樣,在Haskell:
if x `elem` [something, somethingelse] then ...
我想這可以在大多數允許表達列表類型的語言中完成。
在很多編程語言中,你可以做這樣的事情:
myArray[something, somethingElse].Contains(x)
...但我的猜測是,它會執行略差。
我的快速測試顯示,在python中,「if x == 3或x == 5」和「if in [3,5]」中的性能幾乎完全相同。但是,我毫不懷疑測試可能更加完整和確鑿。 – Cdsboy
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;
}
在語言中有 「開關」 操作,你可以這樣做:
switch (x)
{
case 1:
case 2:
{
// do whatever
break;
}
default:
{
// else case
break;
}
}
它有點冗長,但在C中你可以隱藏它在一個宏或C + +也許是一個模板。
假設'x'是可以開啓的類型。在C語言和大多數C語言中,這隻適用於整數。 – Thomas
如果'x'不是可以「切換」的東西,那麼可能沒有優化。對於字符串列表,您需要在每個字符串上調用'strcmp()'或等價物,或者使用'for'循環。 –
的Perl:$foo ~~ ['string',$number,qr/regex/]
MATLAB有幾個方法來處理第二種形式你上面所列內容:
if any(x == [something somethingelse]) ...
%# OR
if ismember(x,[something somethingelse]) ...
如果
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比較功能。
Icon programming language支持這個成語很漂亮。Icon是由Ralph Griswold設計的,他已經設計了SNOBOL,它的整個評估模型建立在成功或失敗之上。一切都構成了,原則上每個表達式都可以產生多重結果。你可以寫這樣的事情
if x == (something | somethingelse) then write("Goodie!")
這裏的評價模型:
something
something
到x
somethingelse
。if
的主體進行評估,並將程序寫入標準輸出。以下是另一個有趣的場景:每個比較要麼成功要麼失敗,如果成功,則返回其右手參數。所以,你可以做的界限與
lo <= x < limit
這個表達式檢查正是如此parenthesizes:
(lo <= x) < limit
所以,如果lo
比x
越大,括號表達式失敗,所以整個事情失敗。 (如果它的任何部分失敗,則普通表達式失敗。)但是,如果lo
最多爲x
,則lo <= x
成功並返回x
。當然,下一步,機器比較x < limit
,如果成功,整個事情就成功了。
圖標是一種非常一致的語言,非常易於使用,並且未被重視。但是它並沒有很好地與操作系統整合在一起,並且當他們有一個和Unix一起使用的版本時,Icon已經失去了獲得思想共享的機會。但是所有的語言設計師都可以通過學習來學習。
R.I.P.
有趣的是,我從來沒有聽說過它。 – Finglas
這是一種欺騙;)你也可以在.NET中使用IList + LINQ來做到這一點。 –
這不是作弊,這是你做這件事的方式。你左邊的東西是免費的! – Thomas
接受,雖然如前所述,它有點作弊,並需要一個列表,而不是在語言構造中直接實現。 – Finglas