I know you can write a statement like:
if (num1 != a && num1 != b && num1 != c ..........&& num1 != z)
(do something);
But is there an easier way to compare the num1 variable to 26 other variables? Kinda like:
if (num1 != a,b,c,d,e,f,g.......)
(do something);
If a..g are contiguous constant/enum values then just use a range check.
if (num >= a && num <= g)
{
do_something();
}
else
{
do_something_else();
}
If they are non-contiguous but constant then maybe use a switch statement.
switch (num)
{
case a:
case b:
case c:
case d:
case e:
case f:
case g:
do_something();
break;
default:
do_something_else();
break;
}
otherwise if they are just arbitrary variables or expressions then you may have just have to do it with multiple tests.
You can put a, ... ,z into a std::set and then use the find method of that set to check if num1 is in there. This has logarithmic complexity, but does not allow for short-circuiting.
First of all, a good code design should not include so many sequence of conditions.
If your case is exactly the way it is, that is trying to see if a number exists in a list, where the list is actually a collection of variables. You could simply enter those numbers into the list( vector ) and perform find operation.
Store the variables in a seperate class / struck if the situation allows for that.
If your question is more about if there is a syntax in c++ to allow a smaler if statement, then perhaps make that clearer in the question.
Use std::find:
static ValueType values[] = { a, b, ... };
// ...
if ( std::find( begin( values ), end( values ), num )
== end( values ) )
Related
I want to apply if statement to check a condition with multiple values, which I know should be something like this:
if (value == 1 || value == 2 || value == 3 || value == 4)
//Do something;
But this does not look good, isn't there any way to check like:
if(value == 1 || 2 || 3 || 4)
Note: I am not trying something in range like:
if (1 <= value && value <= 4)
No you can not write it as :
if(value==1 || 2 || 3 || 4)
You can use conditional statement for different conditions.
A possible simple alternative would be:
switch (value) { case 1: case 2: case 3: case 4: std::cout << "true"; }
Live sample
Wether it looks better or not is a matter of taste.
Another alternative would be:
switch (value) { case 1 ... 4: std::cout << "true"; }
Live sample
But this is not standard C++, I believe it's a GNU extension.
In case the range of possible values is smaller than the number of bits you can do something like this:
int value = 2;
auto values = {1,2,3,4};
int test = 0;
for(auto i : values)
test |= (1 << i);
if((1 << value) & test)
std::cout << "true" << std::endl;
If you have direct control over the possible values you can also directly set them as bitflags and skip the bitshift part.
Otherwise there is also the option of inverting the condition in case there are fewer possible values that should evaluate to false.
Also you could just loop over an array of valid values and see if any of them matches.
No you cannot write the way you have described. You still have option of switch case and ternary operators.
If you want to make it fancy you still have option like
vector<int> v = {1,2,3,4,5}; // desirable values
auto it = find(v.begin(), v.end(), value);
if(it != v.end()){
cout<<"value is equal to something!\n";
// if you want to check which value does it match to
cout<<"Matching value is at index "<<it-v.begin()<<"\n";
}else {
cout<<"Value is not equal to any number!\n";
}
For this you will need to include vector library by using #include <vector>
Well, I had the same issue and this is the solution I came up.
I created an array, with the values I want to check, and then I use the native array includes() method to check if the variable value exists on the array. Like this:
[1, 2, 3, 4].includes(value);
If the variable value exists on the array the includes() method will return a boolean with the value true. Otherwise it will return a boolean with the value false.
New here. I was just wondering if it's possible to make this if statement shorter and less redundant.
if (!a && b)
{
if (c == d && e > 0)
{
return;
}
}
else if (a && !b)
{
if (c != d)
{
return;
}
}
else if (!a && !b)
{
return;
}
Here's what I've ended up with
if ((!a && b && c == d && e > 0) || (a && !b && c != d) || (!a && !b))
{
return;
}
All I did was join nested if statements with an && operator, and if-else if statements with || operator. Now I'm stuck, is it possible to make this even shorter? If you could share some tips or your way of approaching this kind of scenario, I'd be glad to hear it out.
Neither of the approaches is readable. It will be better to create a function that indicates the kinds of checks you are performing.
if ( !my_very_sensible_special_conditions_are_met(a, b, c, d, e) )
{
return;
}
After that, whether you use the first approach or the second approach in the implementation of the function is less of an issue.
condition ladder(if,else if) shortening
As you mentioned, in all blocks(if, else if) if you are just having the same set of statements then you can put all the conditions with a single if statement with proper conditions with appropriate brackets.By doing this lines of code will get reduced But you will have some disadvantages as per my point of view
Readability will get reduced
In future, if you want to change your code for a particular condition, it will take some time to change.it is not that much easy as you do in condition ladder
if you are not having any problem with the above two points, you can go with your approach itself.But code your conditions as atomic as possible.it will help you out in a long run.
Given the number and complexity of conditions, I'd at least consider making it table driven. For the moment, I've assumed that a and b are actually ints containing either a 0 or a 1.
int index = a | (b<<1) | (int(c==d)<<2) | (int(e>0) << 3);
static const bool should_return[] = {
1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0
};
if (should_return[index])
return;
The table is still basically incomprehensible, but at least it encodes that incomprehensibility fairly compactly, and makes it easy for the code to use it.
Since you commented that you are always returning, and since your code does not specify if you do anything else in these if - else cases why not do just
if (! (a && b) )
{
return;
}
You can shorten it a tiny bit further:
if (!a && !b || !b && c != d || !a && c==d && e> 0) {
return;
}
But that doesn't increase readability and most likely also not performance. What I would focus on is, what reads most natural with the real variable names.
As a general advice, I'd start with checking the simpler / shorter conditions first. That makes it often more easier to see if you make redundant checks in the following ones.
In any case, as #R.Sahu suggested, a complex condition like that belongs into a separate, named and commented function. If you don't find a good name for it use something generic like e.g. check_<main_function>_preconditions.
EDIT:
Sorry, I can't resist: If you wan to go overboard, you can make it pretty compact by throwing in a trinary statement:
if (!a && !b || c != d ? !b : !a && e> 0) {
return;
}
DON'T do that in production code!
I am working on a game, and I am finding myself very often checking that certain quantities are in the bounds of the indexes accepted by the vector that represents my world:
if(a >= 0 && a < 16 && b >= 0 && b < 16 && c >= 0 && c < 16 &&
d >= 0 && d < 16 && e >= 0 && e < 16)
{
//do things with vector[a][b][c][d][e]
}
I often have to check even more conditions than this. Is there a way that I can make these checks more concise and/or easier to read?
Alternatively, is there a way that I can avoid doing the checks entirely? The vector is 16x16x16x16x16; can I make it so that if I were to give it a 16 as an index, it would do nothing rather than segfault?
You could write a variadic check function:
bool check(int a) {
return 0 <= a && a < 16;
}
template<typename... Args>
bool check(int a, Args... args) {
return check(a) && check(args...);
}
You can use it like check(a, b, c, d, e, ...). It also has the advantage of being able to take any number of conditions.
Here's a demo
Here's a compact and efficient way to do the check. It assumes two's complement arithmetic.
bool IsInBounds(int a, int b, int c, int d, int e)
{
// Make sure only bits 0-3 are set (i.e. all values are 0-15)
return ((a | b | c | d | e) & ~0xf) == 0;
}
This works by noting that all values outside the 0-15 range all have a bit set that isn't one of the four least significant ones, and all values inside the range don't.
Of course it's only worth using this sort of optimization if the gains in efficiency outweigh the loss of code readability.
The point of functions is reusability. If you find yourself writing certain long expressions or groups of statements repeatedly, it might be time to refactor it out.
In this case, I would write a simple function to do the bounds checking:
bool isInBounds(int a, int b, int c, int d, int e)
{
return a >= 0 && a < 16 &&
b >= 0 && b < 16 &&
c >= 0 && c < 16 &&
d >= 0 && d < 16 &&
e >= 0 && e < 16;
}
Then use it instead of your long condition:
if (isInBounds(a, b, c, d, e))
{
// do things with array[a][b][c][d][e]
}
You can store your variables as elements in a std::vector rather than separate variabes like this:
bool test(const std::vector<int>& values)
{
for(auto v: values)
if(v < 0 || v >= 16)
return false;
return true;
}
Alternatively if you are using C++11 or later you can use std::all_of:
if(std::all_of(std::begin(values), std::end(values),
[](int i){ return i >= 0 && i < 16; }))
{
// do stuff with values
}
In that case you may also be able to use a std::array.
You could combine the 5 integers making up your index into one std::array or your own class.
using Index5 = std::array<int, 5>;
Then you can write a function like:
bool contains(Index5 bounds, Index5 point) {
for (Index5::size_type d = 0; d != bounds.size(); ++d) {
if ((unsigned)point[d] > bounds[d]) // using the trick mentioned in comments
return false;
}
return true;
}
Then use it like this:
auto bounds = Index5{16, 16, 16, 16, 16};
auto point = Index5{a, b, c, d, e};
if (contains(bounds, point)) {
// do things with point
}
Generally, I would suggest using something like Index5 instead of managing five integers.
If the quantities a, b, c, d, and e are something that occur
together quite frequently and all need to stay within the bounds
of your "world" (e.g. they represent the "state" of something in that world)
then it might make sense to define a class whose primary purpose is
to hold one "state" consisting of those five quantities.
Then make sure that if any code ever tries to store values in an object
of that class that are not within the bounds, something reasonable
(not a segfault) happens instead,
and no out-of-bounds values are ever stored there.
That way, an object of that class is safe to pass to any function that
requires a, b, c, d, and e to be within bounds,
and there is no need for any such function to do bounds-checking
on those five values.
In C++ want to write something like this
int Answer;
if (Answer == 1 || Answer == 8 || Answer == 10)
and so on, is it any way to make code shorter without repeating variable always?
Try:
switch (Answer) {
case 1: // fall through
case 8: // fall through
case 10:
// ... do something
break; // Only need if there are other case statements.
// Leaving to help in mainenance.
}
For readability I'd encapsulate the logic in descriptively-named functions. If, say, your answers are things with a particular color, and answers 1, 8, and 10 are green things, then you can write that logic as
bool ChoiceIsGreen(int answer)
{
return (answer == 1 || answer == 8 || answer == 10);
}
Then your function becomes
if (ChoiceIsGreen(Answer))
{
// offer some soylent green
}
If you have a lot of choices like this, I can see it getting hard to read if you have a lot of raw numbers all over the place.
If and only if you need to optimise for code size manually, and Answer is guaranteed to be positive and less than the number of bits in an int, you might use something like
if ( ( 1 << Answer ) & 0x502 )
But normally you don't want to obscure your logic like that.
You could put the values into a container and search the container.
Sounds like a std::set would be a wise choice:
if answer is in the set of (1, 8, 10) then do....
Remember that a std::set must be initialized during run-time, unlike numeric constants or an array of numeric constants. Before making any performance changes, first get the program working correctly, then profile if necessary, that is only if the program demands performance optimization.
If you want to some code to execute based on two or more conditions which is the best way to format that if statement ?
first example:-
if(ConditionOne && ConditionTwo && ConditionThree)
{
Code to execute
}
Second example:-
if(ConditionOne)
{
if(ConditionTwo )
{
if(ConditionThree)
{
Code to execute
}
}
}
which is easiest to understand and read bearing in mind that each condition may be a long function name or something.
I prefer Option A
bool a, b, c;
if( a && b && c )
{
//This is neat & readable
}
If you do have particularly long variables/method conditions you can just line break them
if( VeryLongConditionMethod(a) &&
VeryLongConditionMethod(b) &&
VeryLongConditionMethod(c))
{
//This is still readable
}
If they're even more complicated, then I'd consider doing the condition methods separately outside the if statement
bool aa = FirstVeryLongConditionMethod(a) && SecondVeryLongConditionMethod(a);
bool bb = FirstVeryLongConditionMethod(b) && SecondVeryLongConditionMethod(b);
bool cc = FirstVeryLongConditionMethod(c) && SecondVeryLongConditionMethod(c);
if( aa && bb && cc)
{
//This is again neat & readable
//although you probably need to sanity check your method names ;)
}
IMHO The only reason for option 'B' would be if you have separate else functions to run for each condition.
e.g.
if( a )
{
if( b )
{
}
else
{
//Do Something Else B
}
}
else
{
//Do Something Else A
}
Other answers explain why the first option is normally the best. But if you have multiple conditions, consider creating a separate function (or property) doing the condition checks in option 1. This makes the code much easier to read, at least when you use good method names.
if(MyChecksAreOk()) { Code to execute }
...
private bool MyChecksAreOk()
{
return ConditionOne && ConditionTwo && ConditionThree;
}
It the conditions only rely on local scope variables, you could make the new function static and pass in everything you need. If there is a mix, pass in the local stuff.
if ( ( single conditional expression A )
&& ( single conditional expression B )
&& ( single conditional expression C )
)
{
opAllABC();
}
else
{
opNoneABC();
}
Formatting a multiple conditional expressions in an if-else statement this way:
allows for enhanced readability:
a. all binary logical operations {&&, ||} in the expression shown first
b. both conditional operands of each binary operation are obvious because they align vertically
c. nested logical expressions operations are made obvious using indentation, just like nesting statements inside clause
requires explicit parenthesis (not rely on operator precedence rules)
a. this avoids a common static analysis errors
allows for easier debugging
a. disable individual single conditional tests with just a //
b. set a break point just before or after any individual test
c. e.g. ...
// disable any single conditional test with just a pre-pended '//'
// set a break point before any individual test
// syntax '(1 &&' and '(0 ||' usually never creates any real code
if ( 1
&& ( single conditional expression A )
&& ( single conditional expression B )
&& ( 0
|| ( single conditional expression C )
|| ( single conditional expression D )
)
)
{
... ;
}
else
{
... ;
}
The first example is more "easy to read".
Actually, in my opinion you should only use the second one whenever you have to add some "else logic", but for a simple Conditional, use the first flavor. If you are worried about the long of the condition you always can use the next syntax:
if(ConditionOneThatIsTooLongAndProbablyWillUseAlmostOneLine
&& ConditionTwoThatIsLongAsWell
&& ConditionThreeThatAlsoIsLong) {
//Code to execute
}
Good Luck!
The question was asked and has, so far, been answered as though the decision should be made purely on "syntactic" grounds.
I would say that the right answer of how you lay-out a number of conditions within an if, ought to depend on "semantics" too. So conditions should be broken up and grouped according to what things go together "conceptually".
If two tests are really two sides of the same coin eg. if (x>0) && (x<=100) then put them together on the same line. If another condition is conceptually far more distant eg. user.hasPermission(Admin()) then put it on it's own line
Eg.
if user.hasPermission(Admin()) {
if (x >= 0) && (x < 100) {
// do something
}
}
The second one is a classic example of the Arrow Anti-pattern So I'd avoid it...
If your conditions are too long extract them into methods/properties.
The first one is easier, because, if you read it left to right you get:
"If something AND somethingelse AND somethingelse THEN" , which is an easy to understand sentence. The second example reads "If something THEN if somethingelse THEN if something else THEN", which is clumsy.
Also, consider if you wanted to use some ORs in your clause - how would you do that in the second style?
In Perl you could do this:
{
( VeryLongCondition_1 ) or last;
( VeryLongCondition_2 ) or last;
( VeryLongCondition_3 ) or last;
( VeryLongCondition_4 ) or last;
( VeryLongCondition_5 ) or last;
( VeryLongCondition_6 ) or last;
# Guarded code goes here
}
If any of the conditions fail it will just continue on, after the block. If you are defining any variables that you want to keep around after the block, you will need to define them before the block.
I've been facing this dilemma for a long time and I still can't find a proper solution. In my opinion only good way is to first try to get rid of conditions before so you're not suddenly comparing 5 of them.
If there's no alternative then like others have suggested - break it down into separete ones and shorten the names or group them and e.g. if all must be true then use something like "if no false in array of x then run".
If all fails #Eoin Campbell gave pretty good ideas.
When condition is really complex I use the following style (PHP real life example):
if( $format_bool &&
(
( isset( $column_info['native_type'] )
&& stripos( $column_info['native_type'], 'bool' ) !== false
)
|| ( isset( $column_info['driver:decl_type'] )
&& stripos( $column_info['driver:decl_type'], 'bool' ) !== false
)
|| ( isset( $column_info['pdo_type'] )
&& $column_info['pdo_type'] == PDO::PARAM_BOOL
)
)
)
I believe it's more nice and readable than nesting multiple levels of if(). And in some cases like this you simply can't break complex condition into pieces because otherwise you would have to repeat the same statements in if() {...} block many times.
I also believe that adding some "air" into code is always a good idea. It improves readability greatly.