Flow and logic - always testing for direct condition desired. !(!n) != n - php

Sorry in advance, I just don't know how to word this question nor look for it.
I feel like there should be a name for it, some sort of Principle, or Problem, but I don't know it. My title probably doesn't make sense either but I hope it will give enough of a hint.
I want to decide on a way to structure my code for a project. Specifically, nested conditions. In cases where you can't smack them together using AND, etc.
sell_insurance($person): bool {
if ($person->healthy() === true) {
if ($person->rich() === true) {
print 'sold!';
return true;
}
print 'not enough money';
return false;
}
print 'too risky to sell';
return false;
}
Versus:
sell_insurance($person): bool {
if ($person->healthy() !== true) {
print 'too risky';
return false;
}
if ($person->rich() !== true) {
print 'too poor';
return false;
}
print 'sold!';
return true;
}
I think the latter is easier to read, and if there was going to be like 50 nested ifs it would be just ugly. But, I want to make sure I will not run into issues down the line. Something unexpected I won't see from here.
These tests are simple. One thing I'm afraid of, is that not(not a) doesn't necessarily equal a. Sometimes we might expect logic to be boolean when in fact it might not be. I might test person->healthy() !== false, but I might not realize that instead of being true, it might be a string 'almost'. Or something less stupid.
My other concern, is, how to put this? The latter structure defaults to true. It feels less secure than the first approach.
Question to someone with more experience - what are up/downsides to the each approach? Which structure do you stick to, or do you shuffle them around? Thanks
I am learning PHP but I suppose this more or less applies to any language.

In those kind of situation several approuches are possible two of them are:
Using a switch statement to make everything more compact and readable.
But, as Kolos pointed out, it depends on your priorities and general scenarios...
You can even get rid of the logic operators, sometimes I use something like this below, to arrive to simple comparison statements:
$var= $person->healthy() ? 'true' : 'false';
$var.=$person->rich() ? 'true' : 'false';
switch ($var) {
case "truetrue":
echo "SOLD!";
break;
case "falsetrue":
echo "too risky to sell";
break;
case "truefalse":
echo "too poor!";
break;
default:
echo "NO WAY!";
}
Another commonly used is the usage of one or more so-colled guard clauses at the start that covers "corner cases".
In your exemple being rich AND healthy is mandatory, so let's put this as guard clause:
if ($person->healthy() && $person->rich()) {
print "SOLD!";
return true;
} elseif($person->healthy()) {
print "too poor...";
return false;
} elseif($person->rich()) {
print "too risky...";
return false;
} else {
print "NO WAY!";
return false;
}

You could also look at this an other way, either the person is accepted or declined, what makes his request declined could all be shown for example:
if the person is poor and not healthy, you will only "see" that he is not healthy since you returned before checking that.
It all depends on what you want as a priority not only structure wise.
The first approach indicates, that you HAVE to be healthy to get this item,
on the other hand the second one just adds some logic to it (this might not make sense)
If there were way more statements it would all depend on the priority, if you would return from each of them I would take the Second way, but it all depends on what makes more sense, what is easier to understand.

Related

Technical difference on if not then return or if then do

I have a question, might sound simple, but I am trying to understand what or if it makes any technical differences how we write the conditional statements in code. Here I am talking about PHP, but it may apply to other languages as well.
I want to understand if there is any difference between
Check IF NOT then Return
function my_func($var or $val)
{
if ($var != $val) {
return false;
}
// do the stuff ...
}
Check IF then DO
function my_func($var or $val)
{
if ($var == $val) {
// do the stuff ...
}
return false;
}
What I can assume that retuning in IF NOT will be better in performance as if conditions don't match it will not even go through the code. However, that applies to another approach as well. So which one is better or it depends on the situation?
There is probably no performance effect in most languages, so you can just concentrate on clear representation. In most cases it's better to keep inner blocks of code smaller and return earlier, so the preferrable solution depends on the size of "do the stuff" block. If it's one-liner then I'd prefer second example; if not - I'd prefer first example because just returning is one-liner and I don't want to write a lot of code in nested block.
In case both branches of if are one-liners I prefer avoiding unnecessary negation. It doesn't affect performance but slightly affects reading.

Best practice for returning in PHP function/method

I am refactoring an extensive codebase overtime. In the long run we are going to develop the whole system in classes but in the mean time I am using the opportunity to refine my PHP skills and improve some of the legacy code we use across several hundred websites.
I have read conflicting articles over time about how best to return data from a custom function, generally the debate falls into two categories, those concerned about best technical practice and those concerned about ease of reading and presentation.
I am interesting in opinions (with elaboration) on what you consider best practice when returning from a custom PHP function.
I am undecided as to which of the following as a better standard to follow using this basic theoretical function for example;
Approach a.
Populating a return variable and returning it at the end of the function:
<?php
function theoreticalFunction( $var )
{
$return = '';
if( $something > $somethingelse ){
$return = true;
}else{
$return = false;
}
return $return;
}
?>
Approach b.
Returning at each endpoint:
<?php
function theoreticalFunction( $var )
{
if( $something > $somethingelse ){
return true;
}else{
return false;
}
}
?>
A possible duplicate could have been What is the PHP best practice for using functions that return true or false? however this is not limited to simply true or false despite my basic example above.
I have looked through the PSR guidelines but didn't see anything (but I may have missed it so please feel free to point me to PSR with reference :) ).
Extending the original question:
Is the method used to return different depending on the expected/desired output type?
Does this method change depending on the use of procedural or object oriented programming methods? As this question shows, object orientation brings in its own eccentricities to further extend the possible formatting/presentation options Best practices for returns methods in PHP
Please try to be clear in your explanations, I am interested in WHY you choose your preferred method and what, if anything, made you choose it over another method.
I tend towards early returns - leave the function as soon as you know what is going on. One type of this use if called a 'Guard Clause'
Other things I will often do include dropping final else for a default:
if ($something > $somethingelse) {
return true;
}
return false;
and in fact, conditions of the form if (boolean) return true; else return false, can be shortened even further (if it is clearer to you) to just return ($something > $somethingelse);. Extracting a complex if clause from code like this to a usefully named function can help clear up the meaning of code a lot.
There are people arguing for single exit points in functions (only one return at the end), and others that argue for fail/return early. It's simply a matter of opinion and readability/comprehensibility on a case-by-case basis. There is hardly any objective technical answer.
The reality is that it's simply not something that can be prescribed dogmatically. Some algorithms are better expressed as A and others work better as B.
In your specific case neither is "best"; your code should be written as:
return $something > $somethingelse;
That would hopefully serve as example that there's simply no such thing as a generally applicable rule.
I know this question is old but the it is interesting and according to me
there are many things to say about it.
The first thing to say is that there is no real standard about returning in functions or methods.
It's usually ruled by the rules your team has decided to follow, but if you are the only one on this refactoring you can do what you think better.
In the case of returning a value the important thing I guess is
readability. Sometimes it's better to loose a little bit
of performance for a code that is more readable and maintainable.
I will try to show some examples with pros and cons.
Approach A
<?php
function getTariableType($var = null)
{
if (null === $var) {
return 0;
} elseif (is_string($var)) {
return 1;
} else {
return -1;
}
}
Pros:
Explicitness. Each case explains itself, even without any comments.
Structure. There is a branch for each case, every case is delimited clearly
and it's easy to add a statement for a new case.
Cons:
Readability. All these if..else with brackets make the code hard to read and
we really have to pay attention to every part to understand.
Not required code. The last else statement is not required and the code would be
easier to read if the return -1 was only the last statement of the function,
outside of any else.
Approach B
<?php
function isTheVariableNull($var)
{
return (null === $var);
}
Pros:
Readability. The code is easy to read and understand, at the first look we
know that the function is checking whether the variable is null.
Conciseness. There is only one statement and in this case it's fine and clear.
Cons:
Limit. This notation is limited to really little funtions. Using this notation
or even ternary operator becomes harder to understand in more complicated
functions.
Approach C.1
<?php
function doingSomethingIfNotNullAndPositive($var)
{
if (null !== $var) {
if (0 < $var) {
//Doing something
} else {
return 0;
}
} else {
return -1;
}
}
Pros:
Explicitness. Each case is explicit we can reconstruct the logic of the
function when reading it.
Cons:
Readability. When adding many if..else statements the code is really less
readable. The code is then indented many times looks dirty. Imagine the code
with six nested if.
Difficulty to add code. Because the logic seems complex (even if it is not),
it's difficult to add code or logic into the function.
Plenty of logic. If you have many if..else nested it is perhaps because you
should create a second function. NetBeans IDE for example suggests you to create
an other function that handles the logic of all your nested blocks. A function
should be atomic, it should do only one thing. If it does too much work, has
too much logic, it's hard to maintain and understand. Creating an other function
may be a good option.
Approach C.2
This approch aims to present an alternative to the C.1 notation.
<?php
function doingSomethingIfNotNullAndPositive($var)
{
if (null === $var) {
return -1;
} elseif (0 >= $var) {
return 0;
}
//Doing something
}
Pros:
Readability. This notation is very readable. It's
easy to understand what result we will get according to a given value.
Explicitness. As C.1, this approach is explicit in every branch of the
condition.
Cons:
Difficulty to add logic. If the function becomes a bit more complicated,
adding logic would be difficult because we may need to move all the branches of the
condition.
Approach D
<?php
function kindOfStrlen($var)
{
$return = -1;
if (is_string($var)) {
$return = strlen($var);
}
return $return;
}
Pros:
Default value. In this structure we can see that the default value is handled
from the beginning. We have logic in our function, but if we enter in no
branch we have a value anyway.
Ease to add logic. If we need to add a branch if it's easy and it does not
change the structure of the function.
Const:
Not required variable. In this case the $return variable is not required, we
would write the same function without using it. The solution would be to
return -1 at the end, and return strlen($var) in the if, and it would not
be less readable.
Conclusion
I have not listed all the possible notation here, only some of them. What we can
think about them is there is no perfect one, but in some cases an approach seems
better that an other. For example an is_null function would be fine with the
approach B.
Using an approach or an other is really up to you, the important thing is to
choose a logic and to keep it during all your project.
Using the approach b is more fine with me because in approach a you have written very few lines of code, but if there are many lines of code and many return statements, then are chances that i will somewhere use the wrong return type, where $return was assigned a some other place and i did not notice that.
I prever variant b. Not only is it more readable ( you know exactly that you do not need to consider any of the remaining code after a return statement), but it is also more failsafe.
If you either have a bug in the remaining code, or you encounter a set of conditions you did not take into account when designing the system, it would be possible that your result is changed. This cannot happen when you exit the function with return [$someVariable];
<?php
function theoreticalFunction( $var )
{
if( $something > $somethingelse ){
return true;
}
return false;
}
?>
This approach can also be used as on RETURN Statement, the program cursor is returned back and the next statement will not be executed.

Best practice on ending if...else statement without else condition

What is the best practice to end an if...else statement without an else condition? Consider the following code:
$direction = $_POST['direction']; //Up or down
if ($direction == "up") {
code goes here...
}
elseif ($direction == "down") {
code goes here...
}
else {
//do nothing?
}
As you can see, there's only 2 condition; either up or down and the else statement doesn't really have a purpose unless you want it to display an error message.
Most of the time I see programmers simply put the else condition there but inserts a comment instead of any working code like this.
else {
//error messages goes here...
}
or just assume if it's not 'up' then everything else should be 'down' since there's only 2 condition. If a user inputs 'left' or 'right', it would still be considered as 'down'. I think this is somewhat inappropriate.
if ($direction == 'up') {
code goes here...
}
else {
code goes here...
}
I know that PHP would still work if we put if without else condition. But what if there is an elseif condition? In cases like these, what is the best practice if we want to maintain a strict if...else statement if we do not want to include any error messages or have any else conditions?
Thanks in advance.
There is no if...else statement.
There is only an if statement that can be extended with else and elseif operators.
So, the best practice on if statement without else condition is an if statement without an else condition:
if (condition) {
//some code
}
Frankly, there is no best practice. The best practice is just one that follows the program logic.
That's all
Don't write empty elses. This would just clutter up the code, and it's perfectly obvious what you meant.
In many cases, you can actually use the switch statement:
switch ($_POST['direction') {
case 'up':
// code ...
break;
case 'down':
// code ...
break;
default: // else
throw new Exception('Invalid direction value');
}
I think that if there's nothing to do on else, then there's no need for else block to exist in code. If else block is included, it means that it has a purpose to be there, so the code is incomplete yet, if it is empty.
This isn't something that can take a definite answer. Here's my take, it would be interesting to see what other opinions exist.
Scenario 1: Testing a boolean condition
This is the simplest case:
if (condition) {}
else {}
Specifying a condition as else if would be redundant, and it's really obvious to the reader what the code does. There is no argument for using else if in this case.
Scenario 2: Testing for a subset of infinite states
Here we are interested in testing for conditions A and B (and so on), and we may or may not be interested in what happens if none of them holds:
if (conditionA) {}
else if (conditionB) {}
else {} // this might be missing
The important point here is that there isn't a finite number of mutually-exclusive states, for example: conditionA might be $num % 2 == 0 and conditionB might be $num % 3 == 0.
I think it's natural and desirable to use a reasonable amount of branches here; if the branches become too many this might be an indication that some judicious use of OO design would result in great maintainability improvements.
Scenario 3: Testing for a subset of finite states
This is the middle ground between the first two cases: the number of states is finite but more than two. Testing for the values of an enum-like type is the archetypal example:
if ($var == CONSTANT_FOO) {}
else if ($var == CONSTANT_BAR) {} // either this,
else {} // or this might be missing
In such cases using a switch is probably better because it immediately communicates to the reader that the number of states is finite and gives a strong hint as to where a list of all possible states might be found (in this example, constants starting with CONSTANT_). My personal criteria is the number of states I 'm testing against: if it's only one (no else if) I 'll use an if; otherwise, a switch. In any case, I won't write an else if in this scenario.
Adding else as an empty catch-errors block
This is directly related to scenario #2 above. Unless the possible states are finite and known at compile time, you can't say that "in any other case" means that an error occurred. Seeing as in scenario #2 a switch would feel more natural, I feel that using else this way has a bad code smell.
Use a switch with a default branch instead. It will communicate your intent much more clearly:
switch($direction) {
case 'up': break;
case 'down': break;
default: // put error handling here if you want
}
This might be a bit more verbose, but it's clear to the reader how the code is expected to function. In my opinion, an empty else block would look unnatural and puzzling here.
I sometimes do it like this. I'm not worried that "left"
is interpreted as "down" because I always validate my input, in this case with preg_match('{^up|down$}', $direction). Inarguably a switch is more appropriate... but I dislike the verbose syntax.
if ($direction == "up")
{
// code goes here...
}
else //if ($direction == "down")
{
// code goes here...
}
I try not to write else. Ever. In my experience, using else results in less readable logic, especially when if/elses are being nested.
For assigning a var to either true or false (or any other simple this-or-that value), I always use:
$varx = false;
if ($my_codition_here === true) {
$varx = true;
}
When I have a bigger chunk of logic that you might consider "belongs" in the if/else, I make sure to structure my code so that if the condition is met, the function terminates, usually by returning:
if ($my_codition_here === true) {
// A reasonable amount of logic goes here
return $the_result_up_untill_here;
}
// All logic that would have been "else" goes here.
return $the_result_up_untill_here;
As phihag mentioned; use a switch statement when you consider elseif.
And as Your Common Sense already said, there is no best practise, but there are good practises, and I think this is one.

What is the best way to structure conditional logic? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
It occurs to me that there are number of different ways to structure conditional logic. As far as I can see, as long as we set errors to end the script (or you can imagine the same examples but with a return in a function), then the following examples are equal:
Example 1
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
echo "If either condition was true, we won't see this printed";
Example 2
if(!$condition1) {
if(!$condition2) {
echo "If either condition was true, we won't see this printed";
}
else {
trigger_error("The script is now terminated");
}
}
else {
trigger_error("The script is now terminated");
}
Example 3
if($condition1) {
trigger_error("The script is now terminated");
}
else {
if($condition2) {
trigger_error("The script is now terminated");
}
else {
echo "If either condition was true, we won't see this printed";
}
}
Example 4 -- Adapted from Fraser's Answer
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
test($condition2);
echo "If either condition was true, we won't see this printed";
Personally, I lean towards writing code as in Example 1. This is because I feel that by checking for conditions that end the script (or function) in this way, I can clearly define what the script executed and not executed i.e. everything before the condition has been executed and everything after the line has not. This means when I get an error on line 147, I know immediately what has happened helping me to find a bug faster. Furthermore, if I suddenly realise I need to test $condition2 before $condition1, I can make a change by a simple copy paste.
I see a lot of code written like in Example 2 but for me, this seems much more complex to debug. This is because, when the nesting gets too great, an error will get fired off at some distant line at the bottom and be separated from the condition that caused it by a huge chunk of nested code. Additionally, altering the conditional sequence can be a lot messier.
You could hybrid the two styles, such as in Example 3, but this then seems to overcomplicate matters because all of the 'else's are essentially redundant.
Am I missing something? What is the best way to structure my conditional code? Is there a better way than these examples? Are there specific situations under which one style may be superior to another?
Edit: Example 4 looks quite interesting and is not something I had considered. You could also pass in an error message as a second parameter.
Thanks!
P.S. Please keep in mind that I might need to do some arbitrary steps inbetween checking $condition1 and $condition2 so any alternatives must accommodate that. Otherwise, there are trivially better alternatives such as if($condition1 || $condition2).
I am in the Example 1 camp. As a rule of thumb, the less indentation needed, the better.
// Exit early if there are errors.
if ($n < 0) {
die "bad n: $n";
}
// Handle trivial cases without fuss.
if ($n == 0) {
return 0;
}
/* Now the meat of the function. */
$widget->frob($n);
foreach ($widget->blaxes as $blax) {
checkFrobbingStatus($blax);
}
// ...And another 20 lines of code.
When you use an if/else and put the success and error code in parallel sections you make it appear as if the two code blocks are equal. In reality, the edge cases and error conditions should be de-emphasized. By intentionally handling errors early and then not putting the "important" code in an else clause I feel like that makes it visually clearer where the important code is.
"Here are all the preconditions. And now here's the good stuff."
Personally I hate nested if-else statements so #1 for me from your examples. The other option I would look at is something like the following.
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
//do stuff...
test($condition2);
//passed the tests
EDIT: The more I think about it a functional approach is by far the best way in that it negates having to write the logic that tests the conditions more than once. It also allows greater readability because it is obvious you are 'testing' the condition (as long as you give the function a meaningful name). Also, as pointed out in the question edit it would be trivial to pass other parameters to the function. i.e.
function test($c, $msg) {
if($c) {
trigger_error($msg);
}
}
test($condition1, "condition1 error");
test($condition2, "condition2 error");
#1 is by far the clearest. However, if somehow the thing that previously ended the execution were changed to do something else, then it would break.
It's still probably best to go with #1, but make sure the thing being used to "stop" is clearly named to indicate that it does stop things, so that someone in 10 years maintaining your code doesn't accidentally break things by changing it.
I think your method (example 1) is the most efficient and effective in this type of situation. However, there are times when you do not want any conditions to halt execution and you only want to execute condition2 if condition1 is false. In these situations, an else or elseif works well.
I suggest using ‘try‘ clause over any part that can have errors and use ‘throw "error description"‘ each time an error occures(like example #1).
That way you can have error reporting code once in your program (in the ‘catch‘ clause) and splitting code into functions won't be a hussle rewriting error handlig.
I prefer this style, which doesn't break if either of the conditional blocks are changed so they do not exit execution.
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
if (!$condition1 && !$condition2) {
echo "If either condition was true, we won't see this printed";
}
Edit: Missed the PS, so updated code to match the full question details.
I generally agree with Amber insofar as your first option seems the most legible. This is something I have fought with myself - thus far the only reasoning I have stumbled across is as follows:
The first form is clearest when reading through a linear script, so ideal for simple scripts
The second form is cleanest when you need to ensure tidy / clean-up operations
I mention the second because this is a sticky point. Each script may be part of a larger system, and in fact the script elements you are injecting the "bail out" code into may be called by multiple places. Throw in some OO and you've got a real potential pickle.
The best rule of thumb I can recommend is that if your scripts are simple and linear, or your are doing rapid prototyping, then you want to use the first form and just kill the execution at that point. Anything more complicated or "enterprise-esque" will benefit from (at least) a modular redesign so you can isolate the method and the call stack - and possibly encapsulation of an OO build.
With some of the more powerful debugging and tracing tools which are available these days, it is becoming more a matter of personal style than necessity. One other option you might consider is to put information in comments before (and possibly after) each bail-out zone which make it clear what the alternative is should the criteria be met (or failed).
Edit:
I'd say Fraser's answer is the cleanest for encapsulation. The only thing I would add it that you might benefit from passing an object or hash array into the standard "bail out, I'm dead" method so you can modify the information made available to the function without changing parameter lists all the time (very annoying...).
That said - be careful in production systems where you may need to clean up resources in an intermediate state.
I much prefer #1 as well.
In addition, I really like to assign variables during the conditionals
e.g.
if ( !$userName = $user->login() ) {
die('could not log in');
}
echo "Welcome, $username";
I usually find that in the first write of code, I end up with a fair few messy nested conditional statements, so it's usually during a second pass that I go back and clean things up, un-nest as many of the conditionals that I can.
In addition to looking much neater, I find it conceptually much easier to understand code where you don't have to mentally keep track of branching logic.
For branching logic that can't be removed that contains lots of procedural code, I usually end up putting it in a function / class method -- ideally so I can see on one screen all the branching logic that is taking place, but modifying either the actions or the logic won't break the other one.
Example 5
if($condition1 || $condition2)
{
echo "If either condition was true, we won't see this printed";
}else
{
trigger_error("The script is now terminated");
}
Example 6
function allAreTrue()
{
foreach(func_get_args() as $check)
{
if(!$check)
{
return false;
}
}
return true;
}
if(allAreTrue(true,true,$condition1,$condition2,false))
{
exit("Invalid Arguments");
}
//Continue
The best way to structure conditional logic is to follow the logic itself.
If you have dependencies, say, failing of first condition will make others unnecessary is one thing. Then return, goto, nested conditions and exceptions at your choice.
If you are about to make decision upon a test, say
if (!isset($_GET['id'])) {
//listing part:
} else {
// form displaying part:
}
it's else, elseif and case realm.
etc.
Determine your program logic first and write it's logic then.
and trigger_error() has nothing to do with conditions. It is debugging feature, not program logic related one.

for each ... break

I feel dirty every time I "break" out of a for-each construct (PHP/Javascript)
So something like this:
// Javascript example
for (object in objectList)
{
if (object.test == true)
{
//do some process on object
break;
}
}
For large objectLists I would go through the hassle building a more elegant solution. But for small lists there is no noticeable performance issue and hence "why not?" It's quick and more importantly easy to understand and follow.
But it just "feels wrong". Kind of like a goto statement.
How do you handle this kind of situation?
I use a break. It's a perfectly cromulent solution.
It's quick and more importantly easy to understand and follow.
Don't feel bad about break. Goto is frowned upon because it's quick and more importantly not easy to understand and follow.
See, the break doesn't bug me at all. Programming is built on goto, and for-break - like all control structures - is merely a special-purpose form of goto meant to improve the readability of your code. Don't ever feel bad about writing readable code!
Now, I do feel dirty about direct comparisons to true, especially when using the type-converting equality operator... Oh yeah. What you've written - if (object.test == true) - is equivalent to writing if (object.test), but requires more thought. If you really want that comparison to only succeed if object.test is both a boolean value and true, then you'd use the strict equality operator (===)... Otherwise, skip it.
For small lists, there's no issue with doing this.
As you mention, you may want to think about a more 'elegant' solution for large lists (especially lists with unknown sizes).
Sometimes it feels wrong, but it's all right. You'll learn to love break in time.
Like you said ""why not?" It's quick and more importantly easy to understand and follow."
Why feel dirty, I see nothing wrong with this.
I think is is easier to read and hence easier to maintain.
It is meant to be like it. Break is designed to jump out of a loop. If you have found what you need in a loop why keep the loop going?
Breaks and continues are not gotos. They are there for a reason. As soon as you're done with a loop structure, get out of the loop.
Now, what I would avoid is very, very deep nesting (a.k.a. the arrowhead design anti-pattern).
if (someCondition)
{
for (thing in collection)
{
if (someOtherCondition)
{
break;
}
}
}
If you are going to do a break, then make sure that you've structure your code so that it's only ever one level deep. Use function calls to keep the iteration as shallow as possible.
if (someCondition)
{
loopThroughCollection(collection);
}
function loopThroughCollection(collection)
{
for (thing in collection)
{
if (someOtherCondition)
{
doSomethingToObject(thing);
break;
}
}
}
function doSomethingToObject(thing)
{
// etc.
}
I really don't see anythign wrong with breaking out of a for loop. Unless you have some sort of hash table, dictionary where you have some sort of key to obtain a value there really is no other way.
I'd use a break statement.
In general there is nothing wrong with the break statement. However your code can become a problem if blocks like these appear in different places of your code base. In this case the break statements are code small for duplicated code.
You can easily extract the search into a reusable function:
function findFirst(objectList, test)
{
for (var key in objectList) {
var value = objectList[key];
if (test(value)) return value;
}
return null;
}
var first = findFirst(objectList, function(object) {
return object.test == true;
}
if (first) {
//do some process on object
}
If you always process the found element in some way you can simplify your code further:
function processFirstMatch(objectList, test, processor) {
var first = findFirst(objectList, test);
if (first) processor(first);
}
processFirst(
objectList,
function(object) {
return object.test == true;
},
function(object) {
//do some process on object
}
}
So you can use the power of the functional features in JavaScript to make your original code much more expressive. As a side effect this will push the break statement out of your regular code base into a helper function.
Perhaps I'm misunderstanding your use-case, but why break at all? I'm assuming you're expecting the test to be true for at most one element in the list?
If there's no performance issue and you want to clean up the code you could always skip the test and the break.
for (object in objectList)
{
//do some process on object
}
That way if you do need to do the process on more than one element your code won't break (pun intended).
Use a
Object object;
int index = 0;
do
{
object = objectList[index];
index++;
}
while (object.test == false)
if breaking from a for loop makes you feel uneasy.
My preference is to simply use a break. It's quick and typically doesn't complicate things.
If you use a for, while, or do while loop, you can use a variable to determine whether or not to continue:
for ($i = 0, $c = true; ($i < 10) && $c; $i++) {
// do stuff
if ($condition) {
$c= false;
}
}
The only way to break from a foreach loop is to break or return.

Categories