代码之家  ›  专栏  ›  技术社区  ›  Emil

if语句:if`variable`是“value”或“value”

  •  1
  • Emil  · 技术社区  · 14 年前

    你如何在一个论点中与多种可能性进行比较?

    例子:

    if ((integer == 2) || (integer == 5))
    
    if ((string == "hello") || (string == "dolly))
    

    if (integer == (2 || 5))
    
    if (string == ("hello" || "dolly"))
    
    7 回复  |  直到 14 年前
        1
  •  11
  •   Jens Gustedt    14 年前

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

    为了与编译时积分常量进行比较,在C中有switch语句:

    switch (integer) {
    case 2: ;
    case 5: ;
       /* do stuff here */
    }
    
        2
  •  7
  •   Community CDub    8 年前

    我相信可以这样写:

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

    如果不比较几十个对象,这不会节省很多代码,但这看起来与您想要得到的非常相似:)

    或其他方式(与 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] )
    
        3
  •  3
  •   John Calsbeek    14 年前

    如果你想用一个对象类型,比如说 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"])
    
        4
  •  2
  •   paxdiablo    14 年前

    这不是语言的一部分。如果你真的想避免打字,你 只需创建一个函数来完成它,大致如下:

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

    (与其他数据类型类似)。不过,我对这种方法的有用性表示怀疑,因为(1)对于较长的列表,它只需要较少的输入;以及(2)您可能最终会 "The Daily WTF" :-)

    我的意见是忍住,不是真的 打字太多了。

        5
  •  1
  •   Fernando    14 年前

    Create a variadic function 或接收字符串数组进行比较的字符串。

        6
  •  0
  •   R.. GitHub STOP HELPING ICE    14 年前

    unsigned char wchar_t ,一种方便的方法是:

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

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

    记住这些是八进制值,而不是十进制值。你可以用魔法( \x )如果你愿意的话。

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

        7
  •  0
  •   Vovanium    14 年前

    首先,您应该记住,好的编译器应该优化多个比较,如果它可以得出关于它们的结论,例如,如果值是通过一组文字进行比较的话。所以不需要手工“优化”像x==1 | | x==3 | | x==7这样的表达式。

    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 */
    }