-2
\$\begingroup\$

I was wondering if someone could give some tips as to how improve long strings of if-else statements and redundant if statements. For example, how should I optimize this if statement so it would be more re-usable for maintenance purposes:

   if (($game == 'DS' && $eventId == 185) || ($game == 'MT' && $eventId == 333) || ($game == 'HK' && $eventId == 51) || ($game == 'main' && $eventId == 1166) ||
            ($game == 'WT' && $eventId == 97)) {
/* some code */
}
\$\endgroup\$
3
  • 3
    \$\begingroup\$ You could pair the $game and $eventId variables together as array members and then do a if (in_array($game.$eventId, $matches)) blah.... \$\endgroup\$ Commented Dec 13, 2011 at 2:23
  • 1
    \$\begingroup\$ I tend to shove the data in an array and iterate over that. It's usually a little easier to read/edit/maintain, although it's probably a little slower. \$\endgroup\$
    – Frank Farmer
    Commented Dec 13, 2011 at 2:24
  • 1
    \$\begingroup\$ Could you please be more specific in the use of the in_array function. Should I declare all of values of the the $game and $eventId variables into an array and then use the in_array function to match them up> \$\endgroup\$
    – lollermittens
    Commented Dec 13, 2011 at 2:26

3 Answers 3

2
\$\begingroup\$

I would use the most laziest option possible. Use some string concatenation and a comparison list, as you only need to compare pairs anyway:

if (in_array("$game,$eventId", array("DS,185", "MT,333", "HK,51", "main,1166", "WT,97"))) {

See in_array. You could actually use real array pairs to compare against. But in this instance there's no need.

\$\endgroup\$
11
  • \$\begingroup\$ I type too slow. \$\endgroup\$ Commented Dec 13, 2011 at 2:33
  • \$\begingroup\$ Ha! I beats you! :} Yes, you put too much effort into the testcase. But I see now my , delimiter is redundant, in this case anyway, no ambiguity. \$\endgroup\$
    – mario
    Commented Dec 13, 2011 at 2:38
  • \$\begingroup\$ Well, technically my comment under the question beat you by five minutes, but who's counting? ;) \$\endgroup\$ Commented Dec 13, 2011 at 2:40
  • 1
    \$\begingroup\$ It also occurred to me that an associative array could work just as well and possibly easier, $matches = array('DS'=>185, ...);. \$\endgroup\$ Commented Dec 13, 2011 at 2:42
  • 1
    \$\begingroup\$ I just pretend I didn't notice that. Actually my first idea was strstr("-DS,185-MT,333-HK,52-", "-$a,$b-"), but was afraid of the downvotes, so stole yours. \$\endgroup\$
    – mario
    Commented Dec 13, 2011 at 2:43
2
\$\begingroup\$

Another way would be:

$eventId = $form_values['eventId'];
$game = $form_values['game'];

$games = array(
    'DS'   => 185), 
    'MT'   => 333), 
    'HK'   => 51), 
    'main' => 1166), 
    'WT'   => 97)
);

if(isset($games[$game]) && $games[$game] === $eventId) {
    /* some code */
}

It is hard to tell without knowing where else you might be using the data. If your solution structure can match the real data for the problem then you will get the best result.

I am guessing that games is more complex than just a link to an eventId. If it were more complex then it might look like this:

$games = array(
   'DS' => array('eventId'   => 185,
                 'otherData' => 'blah'),
   'MT' => array('eventId'   => 333,
                 'otherData' => 'nah')
);

if (isset($games[$game]['eventId']) && $games[$game]['eventId'] === $eventId) {
   /* some code */
}
\$\endgroup\$
2
  • \$\begingroup\$ This answer recommends the best data structure for the "lookup" array. An associative array is a logical choice to preserve the paired data in the simplest form. Concatenating the associated values to serve in_array() not only looks/feels hacky, in some fringe cases it can lead to inaccuracies. Paul's method is easy to read/comprehend and will be more welcome in a professional team setting. \$\endgroup\$ Commented Oct 1, 2017 at 4:41
  • \$\begingroup\$ Alternatively, the conditional statement could be: !!array_intersect_assoc($games,[$game=>$eventId]) or !empty(array_intersect_assoc($games,[$game=>$eventId])) if you wanted to make a single expression, but these would be less efficient than Paul's method and allow php to "type juggle" (which probably isn't an issue for this case). If this were my project, I'd be using Paul's method. \$\endgroup\$ Commented Oct 1, 2017 at 4:43
1
\$\begingroup\$

This is one way you could do it:

<?php

$matches = array(
    'DS' . 185,
    'MT' . 333,
    'HK' . 51,
    'main' . 1166,
    'WT' . 97
);

print_r($matches);

$game = 'DS';
$eventId = '185';

if (in_array($game.$eventId, $matches)) {
    echo "You found a match: $game$eventId\n";
} else {
    echo "No match on: $game$eventId\n";
}

$game = 'MT';
$eventId = '185';

if (in_array($game.$eventId, $matches)) {
    echo "You found a match: $game$eventId\n";
} else {
    echo "No match on: $game$eventId\n";
}

$game = 'main';
$eventId = '1166';

if (in_array($game.$eventId, $matches)) {
    echo "You found a match: $game$eventId\n";
} else {
    echo "No match on: $game$eventId\n";
}

?>

http://codepad.org/jYGvuJxx

\$\endgroup\$
2
  • \$\begingroup\$ Jared, isn't there another way to avoid declaring each $game and $eventId before an if-statement? Or does that mean I would have to create a $game = array('MT', 'HK', etc) and $eventId = array(185, 333, etc) and then use these two arrays for comparison purposes using an if-statement? \$\endgroup\$
    – lollermittens
    Commented Dec 13, 2011 at 3:02
  • \$\begingroup\$ That was a demonstration; how you determine it in your actual script is up to you. You keep coming back to this idea that you need two different array()s, one for $games and one for $eventId, and at least in the context of the usage in the if() statement, I can't see it's necessary. If you use an associative array, you can always extract the keys and values to get a list, as well, if you need it for some other reason. \$\endgroup\$ Commented Dec 13, 2011 at 3:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.