Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.
if($row['best']){
    $id = $row['best'];
} elseif($row['average']){
    $id = $row['average'];
} elseif($row['bad']){
    $id = $row['bad'];
} 

If row['best'] is null, I need $id to equal the 2nd best. If 2nd best is null, $id is equal to the next best.

share|improve this question
10  
Can you add a bit of the surrounding context to your question? Where does the $row variable come from? I can imagine that there might be a possible solution where the problem can be fixed elsewhere in your code. –  Simon André Forsberg Mar 31 at 17:10

6 Answers 6

Simon has already answered while I was writing something similar:

foreach(array('best', 'average', 'bad') as $rank) {
  if($row[$rank]) {
    $id = $row[$rank];
    break;
  }
}

Note however, that in both this and Simon's answer, there is a possibility of $id never being assigned a value. Konijn's answer avoids that (although $id might still end up false'y)

share|improve this answer
    
Just assign $id the desired no-match value before the loop. –  David Harkness Apr 4 at 2:03
    
@DavidHarkness Oh sure, it's easy to handle. Just wanted to keep the code 1:1 with OP's question –  Flambino Apr 4 at 8:18

How has no one mentioned the Elvis operator?!

$id = $row['best'] ?: $row['average'] ?: $row['bad'] ?: null;

Substitute your desired "not present" value of choice for null.

Edit: This is the short form of the ternary operator which evaluates to the first expression if truthy or the second expression if not. This is similar to how the || operator is often used in JavaScript.

var options = options || {};
share|improve this answer
    
"Elvis operator"? Never seen that one before, seems to be some ternary-operator-magic there. –  Simon André Forsberg Apr 2 at 11:15
1  
that is pretty slick. thanks! –  Bastien Apr 2 at 20:34
1  
Careful. If $row[xxx] doesn't exist you'll get nasty error notices. –  mAsT3RpEE Apr 2 at 21:42
    
@mAsT3RpEE Correct, same for all of the code on this page. –  David Harkness Apr 3 at 8:38

You may want to write the first_in($arr, $keys) function, and rewrite your code as:

$id = first_in($row, array('best', 'average', 'bad'));

Or more common firstof($arr) function:

$id = firstof(array($row['best'], $row['average'], $row['bad'));

for example, the firstof function:

function firstof($arr) {
    foreach ($arr as $key=>$val)
       if ($val)
           return $val;
    return $arr[count($arr)-1];
}
share|improve this answer

From here:

If there are only 3 possibilities, you could do this:

$id = $row['best'] or $id = $row['average'] or $id = $row['bad'];

This is the closest that PHP can come to JS short circuit assignments.

share|improve this answer
    
I have up to 8 possibilities. For readability, I would rather use if-then-else. No? –  Bastien Mar 31 at 17:41
    
Actually, this could still work with 8, but you would need some newlines, or, you could use @Flambino's approach which is still better than if-then-else –  konijn Mar 31 at 17:44
    
@Bastien Oh, with 8 possibilities I would definitely use one of the iteration methods. You should update your question to reflect this requirement. Programmers tend to be literal creatures at heart. :) –  David Harkness Apr 4 at 1:59

There are some different approaches possible here, one of them is to use an array:

$arr = array($row['best'], $row['average'], $row['bad']);
for ($arr as $value) {
    if ($value) {
       $id = $value;
       break;
    }
}

If you consider this as a better way or not to do what you are trying to accomplish, is really up to you. I can imagine that if the possible options will be extended, then this would be really helpful. But for only three items, your current way is not that bad.

share|improve this answer

Maybe use array functions a bit?

$keys = array_keys($row, TRUE); // returns all keys for which value is boolean TRUE
$id = $keys[0]; // takes first one as ID

Note that this assume only one of the values is set to true or that keys are ordered from the one you want to get the most to one you want the least. It's often a safe assumption, but assumption none the less. Thus, my code is not an universal replacement of your original code, but in many real-life situations it would be pretty good - and it frees you from duplicating lists of possible keys in different parts of the script.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.