自从我开始使用好的VB6
并且直到今天开始编程时,我经常在编程中被烧毁(并且只是):
if x == something or x == somethingelse
我经常写作:
if x == something or somethingelse
出于纯粹的兴趣,那里的语言/语言是否支持这个?
答案 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!")
以下是评估模型:
something
something
与x
somethingelse
。if
的主体,程序写入标准输出。这是另一个有趣的场景:每次比较要么成功要么失败,如果成功,它会返回右手参数。所以你可以用
进行边界检查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等。