Можно ли использовать условное соединение? - PullRequest
0 голосов
/ 02 января 2019

Давайте рассмотрим простой Perl-код:

my @x = ( 1, 5, 9);

for my $i ( 0 .. $#x ) {
    splice( @x, $i, 1 ) if ( $x[$i] >= 5 );
}

print "@x";

Вывод неправильный, 1 9 но должно быть 1

Если мы запускаем код с флагом -w, выводится предупреждение

Use of uninitialized value within @x in numeric ge (>=) at splice.pl line 5.

Итак, не рекомендуется использовать условное сращивание и лучше выдвинуть результат в новую переменную?

1 Ответ

0 голосов
/ 02 января 2019

Проблема не в том, что вы используете условное splice само по себе, а в вашем цикле.Самая очевидная проблема, которая вызывает ваше предупреждение, состоит в том, что вы бежите из конца массива.for my $i ( 0 .. $#x ) устанавливает конечную точку итерации равной $#x до цикла, но после объединения одного или нескольких элементов последний индекс массива будет меньше.Вы можете исправить это, используя цикл for в стиле C вместо цикла в стиле range, но я не рекомендую этого - продолжайте читать.

Следующая проблема заключается в том, что после склеивания элементаиз массива, вы продолжаете цикл с $i на единицу выше ... но поскольку вы склеили элемент из массива, следующий элемент, который вы еще не видели, находится в $x[$i], , а не $x[$i+1].Вы говорите: «Вывод правильный, 1 9», но не нужно было удалить 9, поскольку его больше 5?Вы можете исправить это, используя redo после splice, чтобы снова пройти через цикл, не увеличивая $i, но я не рекомендую также.

Так что возможно исправьте ваш цикл, который использует splice, чтобы он работал правильно, но результат был бы довольно сложным.Если нет веских причин сделать это по-другому, я бы порекомендовал использовать просто

@x = grep { $_ < 5 } @x;

Нет проблем с назначением результата тому же массиву, что и у источника, и для вас нет управления циклами или другой служебной работы для вас.делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...