Есть что-то вроде `last` для` map`?

В Perl можно произвольно закончить выполнение map, например. что-то эквивалентное last в цикле?

Это будет примерно так:

map {
    if (test == true) { last; } dosomething
} @myarray

Ответы

Ответ 1

Неа. Вы не можете last, next и т.д. Из блоков map, grep или sort, потому что они не являются петлями.

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

Вот лучший способ написать его, если вы действительно должны его встроить (изменено после ysth comment):

 $_ == 10 && last, print for 1..15;  # prints '123456789'

Ответ 2

Нет. Используйте порядковый цикл foreach и оператор last.

Начиная с 5.8.1, карта контекстно-зависимая - в пустотном контексте не создаются списки. В любом случае, карта обычно используется для получения списка из другого списка, оценивая выражение для каждого элемента исходного списка.

Ответ 3

Вы можете использовать do-block с модификатором for:

do {
   last if test;
   dosomething;
} for (@myarray);

Хотя использование блока foreach, вероятно, будет более ясным, и будущие сопровождающие вашего кода будут благодарны вам.

foreach (@myarray) {
   last if test;
   dosomething;
}

Ответ 4

Вы можете использовать длинный прыжок (пара eval/die) для спасения любой вложенной конструкции, которая не поддерживает ее напрямую:

eval { map{ die if test; dosomething } @myarray };

Но, как сказал Зейд, использование цикла for/foreach в этом случае лучше, потому что вы не используете возвращаемое значение map.

Ответ 5

Вы хотите цикл for:

foreach ( @myarray ) { 
    last if test;
    ...
}

Он делает то же самое. map предназначен для преобразования одного списка в другие списки.

Ответ 6

Существуют построчные по карте конструкции, которые делают именно то, что вы хотите сделать. Взгляните на List::Util и List::MoreUtils (удобно также упакованные вместе как List::AllUtils):

use List::MoreUtils 'first';

# get first element with a {foo} key
my $match = map { $_->{foo} eq 'some string' } @elements;

Если вы не хотите извлекать элементы из списка, используйте foreach в соответствии с предыдущими ответами.

Ответ 7

Попробуйте перейти LABEL. Однако я не знаю, насколько это безопасно.