Background:
Often, we developers must check if a single variable is at least one of many options. For example,
if ( (data == 125) || (data == 500) || (data == 750) )
{
/* ... do stuff ...*/
}
The suggestion here (albeit written in C#), provides an elegant solution to use a switch
statement like so,
switch ( data )
{
case 125:
case 500:
case 750:
/* ... do stuff ...*/
break;
default:
/* ... do nothing ... */
break;
}
This works well for "or" conditionals, but is ugly for negated "or" conditionals like the following,
if ( !( (data == 125) || (data == 500) || (data == 750) ) )
{
/* ... do stuff ...*/
}
which could be written as
switch ( data )
{
case 125:
case 500:
case 750:
/* ... do nothing ... */
break;
default:
/* ... do stuff ...*/
break;
}
and seems a bit hackish.
Question:
Is there a more succinct way to check if a single variable is none of many options, like the negated "or" conditional above?
References:
I think the latter is fine.
You can formalize it better, though:
static bool in_sprawling_set(int data)
{
switch ( data )
{
case 125:
case 500:
case 750:
return true;
}
return false;
}
and then where you want to do the work:
if(!in_sprawling_set(data))
{
/* do the work, not in set */
}
This puts the "in set" logic in a function of its own, makes it mildly self-documenting, and the actual use-place much cleaner since the !
becomes more prominent and the final if
is very readable ("if not in sprawling set").
Note: if the number of values is really large, I'd probably go for using a pre-sorted array and a binary search, rather than a huge switch
. I realize a sufficiently clever compiler can do that transform by itself, but the readability of a huge switch
would be rather low (especially if you like to put only one case
per line). There's bsearch()
for the searching:
static int cmp_int(const void *ap, const void *bp)
{
const int a = *(const int *) ap, b = *(const int *) bp;
return a < b ? -1 : a > b;
}
static bool in_sprawling_set(int data)
{
static const int values[] = { 125, 500, 750 };
return bsearch(&data, values, sizeof values / sizeof *values, sizeof *values, cmp_int) != 0;
}
There's quite a lot of boilerplate going on, but you can see how the part that lists the actual values (the only thing that'll grow as more values are added) is more compact.
Instead of negating the condition, you can always use De-morgans laws to simplify the expression
if (data != 125 && data != 500 && data != 750) ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With