可能是重复问题:
为什么大多数编程语言只有二元相等比较运算符?
我有一个简单的问题,自从我开始学习编程语言以来就一直存在。
我想写类似于"如果 x 是 1 或者 2 => 真 (否则为假)"的代码。
但当我在编程语言中写它,比如 C 语言时,
( x == 1 || x == 2 )
它真的可以工作,但看起来很笨拙且难以阅读。我想应该可以简化这样的或操作,如果您有任何想法,请告诉我。谢谢,Nathan
可能是重复问题:
为什么大多数编程语言只有二元相等比较运算符?
我有一个简单的问题,自从我开始学习编程语言以来就一直存在。
我想写类似于"如果 x 是 1 或者 2 => 真 (否则为假)"的代码。
但当我在编程语言中写它,比如 C 语言时,
( x == 1 || x == 2 )
它真的可以工作,但看起来很笨拙且难以阅读。我想应该可以简化这样的或操作,如果您有任何想法,请告诉我。谢谢,Nathan
Python允许检查一个序列中是否包含某个元素:
if x in (1, 2):
一个C#扩展版本
步骤1:创建一个扩展方法
public static class ObjectExtensions
{
public static bool Either(this object value, params object[] array)
{
return array.Any(p => Equals(value, p));
}
}
步骤2:使用扩展方法
if (x.Either(1,2,3,4,5,6))
{
}
else
{
}
(Array.IndexOf(values, value) > -1)
即可,这样您就不必创建新列表。 - Jess虽然这个帖子中有一些相当有趣的回答,但我想指出,如果你在循环内部执行此类逻辑,这些回答可能会对性能产生影响,具体取决于语言。就计算机理解而言,if (x == 1 || x == 2)
明显是最容易理解和优化的,因为它可以编译成机器代码。
x in (1, 2)
иҮіе°‘дёҺPythonз”ҹжҲҗзҡ„д»Јз Ғx == 1 or x == 2
дёҖж ·дјҳеҢ–гҖӮеҪ“然пјҢеңЁCиҜӯиЁҖдёӯпјҢзӣёеҸҚзҡ„жғ…еҶөд№ҹжҳҜеҰӮжӯӨгҖӮ - intuitedtime
进行测量,如果x
为1,则in
需要0.042秒,而or
需要0.047秒;如果x
为2或0,则两者都需要0.08秒。 因此,如果您正在进行Python的微优化,请注意您正在测试的条件的顺序... - Tim Pietzcker当我开始编程时,我也觉得很奇怪,因为它并不像:
(1 < x < 10)
我不得不写:
(1 < x && x < 10)
但这是大多数编程语言的工作方式,过一段时间后你会习惯的。( x == 1 || x == 2 )
这样编写代码的优势在于其他程序员可以轻松理解你的写法。使用一个函数来封装它可能只会让事情变得更加复杂,因为其他程序员需要找到那个函数并看看它是做什么的。
只有像Python、Ruby等较新的编程语言才允许您以更简单、更美观的方式编写代码。这主要是因为这些编程语言旨在提高程序员的生产力,而较旧的编程语言的主要目标是应用程序的性能,而不是程序员的生产力。
你的方法似乎更自然,但这实际上取决于你用于实现的编程语言。
由于C是一种系统编程语言,并且与硬件接近(尽管我们曾经认为它是“高级”语言,而不是编写机器代码),因此它并不是非常表达能力强。
现代高级语言(虽然历史上来说Lisp并不算现代,但它可以很好地完成这个任务)通过使用内置结构或库支持(例如,在Python、Ruby、Groovy、ML-languages、Haskell等语言中使用Ranges、Tuples或相当的结构)使您能够完成这样的事情。
您的一个选择是实现一个函数或子例程,它接受一个值数组并对它们进行检查。
这里是一个基本的原型,我将实现留作练习给您:
/* returns non-zero value if check is in values */
int is_in(int check, int *values, int size);
然而,很快就会发现,这只是非常基本的,不太灵活:
在复杂性(语言方面)的阶梯上更进一步,另一个选择是使用预处理器 宏在C(或C ++)中实现类似的行为,但要注意副作用。
下一步可以将函数指针作为额外参数传递以在调用点定义行为,为此定义几个变体和别名,并构建自己的比较器小库。
接下来的步骤就是使用模板在C++中实现类似的东西,以便使用单一实现处理不同类型。通常,支持functional programming的语言将内置对此类事物的支持,原因显而易见。
或者只需学会接受某些语言可以做到其他语言无法做到的事情,并且根据工作和环境的不同,这就是事实。这主要是语法糖,你无能为力。此外,一些语言将通过更新其规范来解决其缺点,而其他语言则会停滞不前。
也许已经有一个库实现了这样的功能,而我不知道。
这里有很多有趣的替代方案。我很惊讶没有人提到switch...case - 所以我来说一下:
switch(x) {
case 1:
case 2:
// do your work
break;
default:
// the else part
}
出错了,它有什么问题?好吧,如果你真的经常使用它并且不喜欢外观,请在c#中执行以下操作:
#region minimizethisandneveropen
public bool either(value,x,y){
return (value == x || value == y);
}
#endregion
并在使用它的地方:
if(either(value,1,2))
//yaddayadda
或者在另一种语言中类似的东西 :).
return (value == x || value == y);
- Karel Petranekvalue
放在第一位(但这只是我的个人看法),而且 x
被使用了两次,一次作为 value
,一次作为第一个参数。 - Kobi我觉得我不会这样做,但为了回答你的问题,这里有一种在C#中实现它的方法,它涉及一些泛型类型推断和对运算符重载的滥用。您可以编写以下代码:
if (x == Any.Of(1, 2)) {
Console.WriteLine("In the set.");
}
在这里,Any
类的定义如下:
public static class Any {
public static Any2<T> Of<T>(T item1, T item2) {
return new Any2<T>(item1, item2);
}
public struct Any2<T> {
T item1;
T item2;
public Any2(T item1, T item2) {
this.item1 = item1;
this.item2 = item2;
}
public static bool operator ==(T item, Any2<T> set) {
return item.Equals(set.item1) || item.Equals(set.item2);
}
// Defining the operator== requires these three methods to be defined as well:
public static bool operator !=(T item, Any2<T> set) {
return !(item == set);
}
public override bool Equals(object obj) { throw new NotImplementedException(); }
public override int GetHashCode() { throw new NotImplementedException(); }
}
}
Any.Of
方法来处理3、4甚至更多个参数。也可以提供其他操作符,并且一个伴随类 All
可以执行非常类似的操作,但将 &&
替换为 ||
。 Equals
,因此会发生相当多的装箱操作,所以这比明显的(x == 1)||(x == 2)
构造要慢。但是,如果您将所有<T>
更改为 int
并将 Equals
替换为 ==
,则得到的结果似乎可以很好地内联,速度与(x == 1)||(x == 2)
大致相同。inline int contains(int[] set, int n, int x)
{
int i;
for(i=0; i<n; i++)
if(set[i] == x)
return 1;
return 0;
}
// To implement the check, you declare the set
int mySet[2] = {1,2};
// And evaluate like this:
contains(mySet,2,x) // returns non-zero if 'x' is contained in 'mySet'
int[] wanted = new int{1, 2};
// you can use Any to return true for the first item in the list that passes
bool result = wanted.Any( i => i == x );
// or use Contains
bool result = wanted.Contains( x );
虽然我个人认为基本的||
非常简单:
bool result = ( x == 1 || x == 2 );