Can the for loop be eliminated from this piece of PHP code?

后端 未结 10 1096
夕颜
夕颜 2020-12-11 04:59

I have a range of whole numbers that might or might not have some numbers missing. Is it possible to find the smallest missing number without using a loop structure? If ther

10条回答
  •  -上瘾入骨i
    2020-12-11 05:50

    I honestly don't get why you wouldn't want to use a loop. There's nothing wrong with loops. They're fast, and you simply can't do without them. However, in your case, there is a way to avoid having to write your own loops, using PHP core functions. They do loop over the array, though, but you simply can't avoid that.
    Anyway, I gather what you're after, can easily be written in 3 lines:

    function highestPlus(array $in)
    {
        $compare = range(min($in), max($in));
        $diff = array_diff($compare, $in);
        return empty($diff) ? max($in) +1 : $diff[0];
    }
    

    Tested with:

    echo highestPlus(range(0,11));//echoes 12
    $arr = array(9,3,4,1,2,5);
    echo highestPlus($arr);//echoes 6
    

    And now, to shamelessly steal Pé de Leão's answer (but "augment" it to do exactly what you want):

    function highestPlus(array $range)
    {//an unreadable one-liner... horrid, so don't, but know that you can...
         return min(array_diff(range(0, max($range)+1), $range)) ?: max($range) +1;
    }
    

    How it works:

    $compare = range(min($in), max($in));//range(lowest value in array, highest value in array)
    $diff = array_diff($compare, $in);//get all values present in $compare, that aren't in $in
    return empty($diff) ? max($in) +1 : $diff[0];
    //-------------------------------------------------
    // read as:
    if (empty($diff))
    {//every number in min-max range was found in $in, return highest value +1
        return max($in) + 1;
    }
    //there were numbers in min-max range, not present in $in, return first missing number:
    return $diff[0];
    

    That's it, really.
    Of course, if the supplied array might contain null or falsy values, or even strings, and duplicate values, it might be useful to "clean" the input a bit:

    function highestPlus(array $in)
    {
        $clean = array_filter(
            $in,
            'is_numeric'//or even is_int
        );
        $compare = range(min($clean), max($clean));
        $diff = array_diff($compare, $clean);//duplicates aren't an issue here
        return empty($diff) ? max($clean) + 1; $diff[0];
    }
    

    Useful links:

    • The array_diff man page
    • The max and min functions
    • Good Ol' range, of course...
    • The array_filter function
    • The array_map function might be worth a look
    • Just as array_sum might be

提交回复
热议问题