自从我开始编程适当的编程用好老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