更快的if语句:如果`variable`是“value”或“value”

时间:2010-10-23 21:42:05

标签: objective-c c language-agnostic ios

如何在一个参数中与多种可能性进行比较?

示例:

if ((integer == 2) || (integer == 5))

if ((string == "hello") || (string == "dolly))
如果您可以这样编写代码,那么会为我节省很多代码:

if (integer == (2 || 5))

if (string == ("hello" || "dolly"))

7 个答案:

答案 0 :(得分:11)

首先,字符串比较在C中不起作用,我对Objective-c一无所知,思想。

对于编译时积分常数的比较,在C中你有switch语句:

switch (integer) {
case 2: ;
case 5: ;
   /* do stuff here */
}

答案 1 :(得分:7)

实际上,您可以检查NSSet是否包含某个对象。这不适用于int,因为它不是一个对象,但可以使用NSString。

我相信它可以这样写:

if ( [[NSSet setWithObjects:@"hello", @"dolly", nil] containsObject:string] )

因此,如果你想比较整数,你应该用NSNumber包装它们。

如果您不是在比较数十个对象,这将无法保存大量代码,但这看起来非常类似于您想要的内容:)

<强>更新

或另一种方式(与answer from John Calsbeek非常相似,但适用于多个参数):

@implementation NSObject (IsEqualMultiple)

- (BOOL)isEqualToOneOfObjects:(id)firstObject, ... {
    id eachObject;
    va_list argumentList;

    if (firstObject) {
        if ( [self isEqual:firstObject] ) return YES;

        va_start(argumentList, firstObject);

        while (eachObject = va_arg(argumentList, id))
            if ( [self isEqual:eachObject] ) return YES;
        va_end(argumentList);
    }

    return NO;
}

@end

用法:

if ( [string isEqualToOneOfObjects:@"hello", @"dolly", @"this", @"is", @"Louis", nil] )

答案 2 :(得分:3)

如果您想使用对象类型执行此操作,例如说NSString,并且您对类别感到满意,则可以添加类别方法:

@implementation NSObject (IsEqualMultiple)

- (BOOL)isEqualTo:(id)obj1 or:(id)obj2 
{
    return [self isEqual:obj1] || [self isEqual:obj2];
}

@end

然后你可以像这样使用它:

if ([string isEqualTo:@"hello" or:@"dolly"])

答案 3 :(得分:2)

这不是该语言的一部分。如果你真的想避免输入,那么可以创建一个函数来执行它,类似于:

int intIsIn (int needle, int *haystack, size_t sz);
:
if (intIsIn (integer, {2,5}, 2)) ...

(和其他数据类型类似)。我质疑这种方法的用处,但是因为(1)对于较长的列表而言,它的输入较少; (2)你最终可能会以"The Daily WTF"结束: - )

我的意见是,只是吮吸它,它不是真的 打字很多。

答案 4 :(得分:1)

Create a variadic function或接收用于比较的字符串数组的那个。

答案 5 :(得分:0)

如果您的整数非零且小到足以适合unsigned charwchar_t,那么执行此操作的便捷方法如下:

if (strchr("\2\5", integer)) ...

或:

if (wcschr(L"\2\5", integer)) ...

请记住,这些是八进制值,而不是十进制。如果您愿意,可以使用十六进制(\x)。

对于字符串,提高效率的方法是使用正则表达式,或者编写自己的DFA来接受要测试的字符串集。

答案 6 :(得分:0)

首先,你应该记住好的编译器应该优化多重比较,如果它可以得出关于它们的结论,例如,如果通过一组文字比较值。所以没有必要'优化'像x == 1 ||这样的表达式x == 3 || x == 7手工制作。

在C中,适用于0..31范围内的整数(或者你的长整数,但你可以使用long long)

if(((1UL<<val1)|(1UL<<val2)|(1UL<<val3)) & (1UL<<x)) ...

这将创建具有与值对应的位数的数字,该值应评估为true。如果你需要与小整数的变量列表进行比较,这很方便。

您也可以使用已排序的值数组和c标准函数bsearch():

int valuelist[] = { /* note it sorted */
    2, 5, 17, 33, 99, 103, 808
}

int valuelist_length = sizeof(valuelist)/sizeof(int);
/* this works only for statically allocated non-external arrays, */
/* you may need another method of evaluating number of items */

int compar_int(const void *a, const void *b) {
    return ((const int *)b < (const int *)a) - ((const int *)a < (const int *)b);
}
...

if(bsearch(&x, valuelist, sizeof(int), valuelist_length, compar_int)) {
    /* bsearch returns pointer to found value or NULL if it is not found */
    /* so it will be evaluated as true if value exists in array */
}

但只有当你有很多数字需要比较时,这才有效。