Возврат “n” элементов из массива, нарушенного равномерно, генерирует stderr

#php #arrays #algorithm

#php #массивы #алгоритм

Вопрос:

У меня есть решение, которое принимает m-element array возвращает n-element array равномерно распределенный. Но для некоторого значения m он генерирует stderr .

Например, если массив будет содержать 15 элементов, то это stderr будет:

  • Уведомление PHP: Неопределенное смещение: -3
  • Уведомление PHP: Неопределенное смещение: -1
  •  class SpredArrayClass
    {
    
    var $array = [1,2,3,4,5,6,7,8,9,9,10,11,12,13,14,15];
    
    function spreadOutArray(array $array = [], $targetOutputLength = 10) {
    
        $array = $this->array;
    
        $originalArrayLength = count($array);
    
        if ($originalArrayLength == 0) {
            return false;
        }
    
        if ($originalArrayLength <= $targetOutputLength) {
            return $array;
        }
    
        $output = [];
        $interval = round($originalArrayLength / $targetOutputLength);
        for ($index = $originalArrayLength - 1; count($output) < $targetOutputLength; $index -= $interval) {
            $output[] = $array[$index];
        }
    
        return array_reverse($output);
        }
    }
      

    Проблема, по-видимому, заключается в этой части:

     $output = [];
    $interval = round($originalArrayLength / $targetOutputLength);
    for ($index = $originalArrayLength - 1; count($output) < $targetOutputLength; $index -= $interval) {
        $output[] = $array[$index];
    }
      

    Undefinded offset stderr появляется в этой строке: $output[] = $array[$index];

    Демонстрация выполнения кода здесь: http://ideone.com/UrF9UK

    Комментарии:

    1. Когда-нибудь слышали о range() ?

    2. Вы могли бы сделать свою жизнь намного проще, используя диапазон php, как правильно намекнул @PHPglue….

    3. Похоже, готовится новый экзамен по кодированию или аналогичный. Подобные вопросы с использованием одних и тех же формулировок уже задавались дважды до сегодняшнего дня…

    4. Вы не можете использовать фиксированное значение для каждого «шага» ($ interval) и в то же время гарантировать правильную выходную длину.

    5. Объясните, что вы подразумеваете под распределением равномерно. An array_splice() ?

    Ответ №1:

    Вы округляете слишком рано. Шаги ($interval) должны быть точными, потому что, если округление вверх, шаги приведут вас слишком быстро к началу массива и приведут к отрицательным индексам.

    Поэтому округляется только при использовании результирующего индекса:

     $interval = $originalArrayLength / $targetOutputLength;
    for ($index = $originalArrayLength - 1; count($output) < $targetOutputLength; $index -= $interval) {
        $output[] = $array[round($index)];
    }
      

    Комментарии:

    1. Принятое вами решение не всегда будет возвращать массив с желаемым количеством элементов, но меньше. Если вы запустите его на образце массива, который вы указали в вопросе, в выходном массиве будет только 8 элементов вместо 10. Вам действительно нужно удалить round из $interval : это неправильная арифметика.

    2. Да, я понял. Вы правы. У меня были дополнительные проблемы с кодом, который я выбрал в качестве решения.

    Ответ №2:

    Ваша проблема связана с условием в вашем for цикле. Измените его на это:

             $output = [];
            $interval = round($originalArrayLength / $targetOutputLength);
    
            // JUST KEEP LOOPING amp; PUSHING TILL SO LONG AS $index IS GREATER THAN 0;
            for($index = $originalArrayLength - 1; $index>=0; $index -= $interval) {
                $output[] = $array[$index];
            }
      

    Комментарии:

    1. Это лучше, потому что он не вызывает round в каждом цикле.