Решая задачи реального мира нам постоянно приходится работать со списками данных. И самые счастливые в этой деятельности — Perl-программисты :)
Это все потому, что для работы с частью массива или хеша у нас есть удобный slice. Slice — это не оператор, это принцип обработки данных, когда от большого объекта отрезается кусочек.
Проще показать:
А вот так выглядит синтаксис анонимных массивов и хешей:
NB. общее правило для анонимных структур —
обозначается всегда как массив, в первых скобках — ссылка на интересующий нас объект, являющийся массивом или хешем, во вторых — перечисление элементов этого объекта.
С многомерным хешем и массивами хешей, ровно как и хешами массиво и т.д. поступаем аналогично, попробуйте сами, это совершенно несложно.
Я же перейду к другому — срезу хеша для создания нового хеша.
Вуаля! Самое главное не забывать предварительно объявлять новый хеш, дальше perl сам создаст требуемые ключи и присвоит им значение из старого хеша. Всяко короче циклов. Да еще и нагляднее.
Правда, есть одна загвоздка — вот для такой структуры
выбрать все значения 'a' и присвоить их новому массиву не получится как-то так:
или так:
Для решения этой задачки мы немного схитрим и возьмем… правильно, map!
Ну а вот такие штуки пригодятся в реальной жизни:
Попробуйте разобраться, сложного абсолютно ничего нет. Соглашусь, что код стал чуть менее читаем, однако его «классический» вариант типа
слишком громоздок.
ИМХО — подробное комментирование меньшего по объему кода куда как целесообразнее кода на уровне школьных учебников без каких-то комментариев. Читать естественный язык проще, быстрее и приятнее.
PS. Пост написан из самых лучших побуждений немного осветить момент, очевидный для профи и непонятный для новичков языка.
Это все потому, что для работы с частью массива или хеша у нас есть удобный slice. Slice — это не оператор, это принцип обработки данных, когда от большого объекта отрезается кусочек.
Проще показать:
my @arr = (1, 3, 5, 7, 9);
my @arr_slice = @arr[2..4]; # (5, 7, 9)
my %hash = ( 'first' => 2, 'second' => 5, 'last' => 99);
my @hash_slice = @hash{'first', 'last'}; # (2, 99)
* This source code was highlighted with Source Code Highlighter.
А вот так выглядит синтаксис анонимных массивов и хешей:
my $arr_ref = [1, 3, 5, 7, 9];
my @arr_ref_slice = @{$arr_ref}[2,3]; # (5, 7)
my $hash_ref = {'first' => 2, 'second' => 5, 'last' => 99};
my @hash_ref_slice = @{$hash_ref}{'second', 'last'}; # (5, 99)
* This source code was highlighted with Source Code Highlighter.
NB. общее правило для анонимных структур —
обозначается всегда как массив, в первых скобках — ссылка на интересующий нас объект, являющийся массивом или хешем, во вторых — перечисление элементов этого объекта.
my $deep_arr = [1, [2, 3, [4, [20, 26, 28]]], 10];
my @deep_arr_slice = @{$deep_arr->[1][2][1]}[0,2]; # (20, 28)
С многомерным хешем и массивами хешей, ровно как и хешами массиво и т.д. поступаем аналогично, попробуйте сами, это совершенно несложно.
Я же перейду к другому — срезу хеша для создания нового хеша.
my @keys = ('first', 'last');
my %old_hash = ( 'first' => 2, 'second' => 6, 'last' => 99);
my %new_hash;
@new_hash{@keys} = @old_hash{@keys};
# (first => 2, last => 99)
Вуаля! Самое главное не забывать предварительно объявлять новый хеш, дальше perl сам создаст требуемые ключи и присвоит им значение из старого хеша. Всяко короче циклов. Да еще и нагляднее.
Правда, есть одна загвоздка — вот для такой структуры
my $complex_ref = [{'a' => 2, 'b' => 5}, {'a' => -4, 'b' => 8}, {'a' => 10, 'b' => -2}];
выбрать все значения 'a' и присвоить их новому массиву не получится как-то так:
my @new_complex = @{$complex_ref}[0..2]{'a'} # wrong!!! syntax error
или так:
my @new_complex = @{$complex_ref->[0..2]}{'a'}; # (-4)???!!!
Для решения этой задачки мы немного схитрим и возьмем… правильно, map!
my @new_complex = map {$_->{'a'}} @{$complex_ref}[0..2];
Ну а вот такие штуки пригодятся в реальной жизни:
my $new_complex_ref = [ map { {'a' => $_->{'a'}, 'c' => ( $_->{'b'} + 3 )} } @{$complex_ref}[0, 2] ];
Попробуйте разобраться, сложного абсолютно ничего нет. Соглашусь, что код стал чуть менее читаем, однако его «классический» вариант типа
my $classic_complex_ref;
for( my $i = 0; $i <= $#{$complex_ref}; $i++ ){
next if ( $i == 1 );
my $a_val = $complex_ref->[$i]{'a'};
my $b_val = $complex_ref->[$i]{'b'};
$b_val += 3;
my $hash = { 'a' => $a_val, 'b' => $b_val};
push @$classic_complex_ref, $hash;
}
* This source code was highlighted with Source Code Highlighter.
слишком громоздок.
ИМХО — подробное комментирование меньшего по объему кода куда как целесообразнее кода на уровне школьных учебников без каких-то комментариев. Читать естественный язык проще, быстрее и приятнее.
PS. Пост написан из самых лучших побуждений немного осветить момент, очевидный для профи и непонятный для новичков языка.