опубликован: 2024-09-25 18:40
последняя редакция: 2024-09-25 18:52
Различия в поведении for, map и grep
Сразу оговорюсь, что изменение исходного массива в процессе выполнения цикла - не самая удачная идея. Тем не менее, для исследования поведения языковых конструкций в перле.. в общем, нам никто не может этого запретить.Итак, довольно стандартная задача: заполнить массив @bbb из элементов массива @aaa по какому-нибудь условию.
Казалось бы, выбор между циклом for, либо map, либо grep - чисто вкусовщина.
Разница оказалась в том, что в процессе цикла for мы можем на ходу изменить исходный массив (а значит - и выходной), а в map/grep - нет. Он там конечно поменяется, но только задним числом.
Я набросал пример, для иллюстрации этого утверждения:
#!/usr/bin/perl
use strict;
use warnings;
sub print_result {
my ($aaa, $bbb) = @_;
local $, = ', ';
print 'aaa: ';
print @$aaa;
print "\nbbb: ";
print @$bbb;
}
my @aaa = (1,2,3);
my @bbb = ();
@bbb = grep { push @aaa, 4 if $_ == 3; $_ } @aaa;
print_result(\@aaa, \@bbb);
print "\n=================\n";
@aaa = (1,2,3);
@bbb = ();
map { push @aaa, 4 if $_ == 3; push @bbb, $_ } @aaa;
print_result(\@aaa, \@bbb);
print "\n=================\n";
@aaa = (1,2,3);
@bbb = ();
for (@aaa) {
push @aaa, 4 if $_ == 3;
push @bbb, $_;
}
print_result(\@aaa, \@bbb);
Помимо абстрактного знания, мы ещё и получаем важный вывод: операторы map/grep сразу "резервируют" весь массив под свою задачу, а оператор for - считывает его поэлементно. С точки зрения работы с памятью (для очень больших массивов), поведение оператора for более экономно.