0

I have to check if a value is withing a range (0..9, 10..19..up to 100) and return a value depending on the range. The cyclomatic complexity of my function is 12 and I need to lower it to at least 9. I'm really at a loss here.

I wanted to use an associative array (to use like a Dictionary or a Hash table), but I don't think it works with ranges and I don't want to have an array explicitly declared with 100 entries!

$value = 23;
switch(true) {
case in_array($value, range(0,9)):
    return -10;
    break;
case in_array($value, range(10,19)):
    return -7;
    break;
case in_array($value, range(20,29)):
    return -5;
    break;
case in_array($value, range(30,39)):
    return 3;
    break;
case in_array($value, range(40,49)):
    return 4;
    break;
case in_array($value, range(50,59)):
    return 5;
    break;
case in_array($value, range(60,69)):
    return 6;
    break;
case in_array($value, range(70,79)):
    return 7;
    break;
case in_array($value, range(80,89)):
    return 8;
    break;
case in_array($value, range(90,99)):
    return 9;
    break;
case in_array($value, range(100,100)):
    return 10;
    break;
default:
    return 0;
    break;
}

Can someone help? Is there a simpler way to do that? TIA

Pinke Helga
  • 6,378
  • 2
  • 22
  • 42
  • 3
    Is this an example, or are these actual numbers you want to return? Because if these are the actual numbers you want to use, you can floor divide by ten if the number is greater than 30. That should remove 8 cases and only add 1 back. – TwoShorts Feb 07 '19 at 03:14
  • That is such a great answer and a easy one. I can't believe I haven't thought of that! Can I blame the fact that both myself and the baby are sick right now.... :P Thanks a lot! – user2224904 Feb 07 '19 at 03:19
  • Using `$value >= 0 && $value <= 9` would be more efficient than `in_array($value, range(0-9)` – Nick Feb 07 '19 at 03:22

2 Answers2

2

Since the steps are regulary each 10, you can perform an integer division by 10 and lookup the corresponding values in an array:

function theFunc(int $i)
{
  return ($i<0 || $i>100) ? 0 : [-10, -7, -5, 3, 4, 5, 6, 7, 8, 9, 10][(int)($i/10)];
}

for($i = -1 ; $i <= 101 ; $i++)
  var_dump([$i, theFunc($i)]);
Pinke Helga
  • 6,378
  • 2
  • 22
  • 42
0

You can just use integer division if the number is greater than 30. You also don't need break; if you are returning, as it will already stop code execution.

switch(true) {
case in_array($value, range(0,9)):
    return -10;
case in_array($value, range(10,19)):
    return -7;
case in_array($value, range(20,29)):
    return -5;
case in_array($value, range(30,100)):
    return intdiv($value, 10);
default:
    return 0;
}
TwoShorts
  • 508
  • 2
  • 7
  • 20