📜 ⬆️ ⬇️

Slice, or very useful slices in Perl

Solving the problems of the real world, we constantly have to work with lists of data. And the most happy in this activity are Perl programmers :)

This is all because we have a convenient slice for working with part of an array or hash. Slice is not an operator, it is a principle of data processing, when a piece is cut off from a large object.
Easier to show:

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 .


And here is the syntax of anonymous arrays and hashes:
')
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. general rule for anonymous structures is
always denoted as an array, in the first brackets - a reference to the object of interest to us, which is an array or hash, and secondly - an enumeration of the elements of this object.

my $deep_arr = [1, [2, 3, [4, [20, 26, 28]]], 10];
my @deep_arr_slice = @{$deep_arr->[1][2][1]}[0,2]; # (20, 28)


With a multi-dimensional hash and an array of hashes, exactly like the hash of an array, etc. do the same, try it yourself, it's completely easy.

I’ll move on to another - cut the hash to create a new hash.

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)



Voila! The most important thing to remember to pre-declare a new hash, then perl itself will create the required keys and assign them a value from the old hash. Any shorter cycles. Yes, and clearer.

True, there is one catch - for such a structure
my $complex_ref = [{ 'a' => 2, 'b' => 5}, { 'a' => -4, 'b' => 8}, { 'a' => 10, 'b' => -2}];

Select all the values ​​of 'a' and assign them to the new array will not work out something like this:
my @new_complex = @{$complex_ref}[0..2]{ 'a' } # wrong!!! syntax error
or so:
my @new_complex = @{$complex_ref->[0..2]}{ 'a' }; # (-4)???!!!

To solve this problem, we cheat a little and take ... right, map!

my @new_complex = map {$_->{ 'a' }} @{$complex_ref}[0..2];

Well, these things will come in handy in real life:

my $new_complex_ref = [ map { { 'a' => $_->{ 'a' }, 'c' => ( $_->{ 'b' } + 3 )} } @{$complex_ref}[0, 2] ];


Try to figure out nothing complicated at all. I agree that the code has become slightly less readable, however its “classic” version of the type

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 .


too cumbersome.

IMHO - detailed commenting on a code that is smaller in terms of where much more expedient is the code at the level of school textbooks without any comments. Reading natural language is easier, faster and more enjoyable.

Ps. The post is written out of the best intentions to light up a bit the moment, obvious to the pros and incomprehensible to newbies of the language.

Source: https://habr.com/ru/post/92995/


All Articles