Есть ли что-то вроде `last` для` map`? - PullRequest
13 голосов
/ 26 августа 2010

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

Было быпримерно так:

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

Ответы [ 7 ]

19 голосов
/ 26 августа 2010

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

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

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

 $_ == 10 && last, print for 1..15;  # prints '123456789'
3 голосов
/ 26 августа 2010

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

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

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

3 голосов
/ 26 августа 2010

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

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

2 голосов
/ 26 августа 2010

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

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

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

2 голосов
/ 26 августа 2010

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

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

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

1 голос
/ 26 августа 2010

Есть картоподобные конструкции, которые делают именно то, что вы хотите. Взгляните на 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, как и в предыдущих ответах.

0 голосов
/ 08 октября 2014

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

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