Emerson Soares
Emerson Soares

Reputation: 21

Perl assign array to hash and vice-versa

I would like to get your help to figure out how to add a long array to a hash key value, how to assign the key value to a temporay array from where the data will be manipulated, than assign the array (or what I have left) back to the same hash key. A sample of what I am looking for is below:

#!/usr/bin/perl 
use strict;

use warnings FATAL => 'all';

My set of arrays that will contain only integers

my @Array1 = ['01', '02', '03', '04', '09', '10', '11', '12']; 
my @Array2 = ['05', '06', '07', '08', '03', '04', '09']; 
my @Array3 = ['09', '10', '11', '12', '02', '03', , '07', '08' ]; 
my @ArrayN = ['N', 'N', 'N', 'N'];

My hash with keys identified by integers (Is it possible?)

my %Hash;

Assigning arrays to key values;

%Hash{'1'} = @Array1 (or $Array1); 
%Hash{'2'} = @Array2 (or $Array2); 
%Hash{'3'} = @Array3 (or $Array3);
%Hash{'N'} = @ArrayN (or $ArrayN);

Assign a hash key value to a temporary array

my @TempArray = $Hash{'1'};

Some process with the temporary array including:

than assign the value back to the hash

%Hash{'1'} = @TempArray;

I have found many posts that are not helping so much, as they don't talk about long arrays.

Upvotes: 0

Views: 2382

Answers (2)

Dave Cross
Dave Cross

Reputation: 69224

My set of arrays that will contain only integers

Actually, your arrays contain strings :-)

my @Array1 = ['01', '02', '03', '04', '09', '10', '11', '12']; 

Here's your first serious error. Arrays are initialised from lists - so you need round brackets, (...), not square brackets, [...].

You wanted this:

my @Array1 = ('01', '02', '03', '04', '09', '10', '11', '12'); 

Alternatively, you could use your original square brackets. But they give you an array reference. A reference is a scalar value, so you store it in a scalar variable.

my $Array1_ref = ['01', '02', '03', '04', '09', '10', '11', '12']; 

My hash with keys identified by integers (Is it possible?)

Well, the keys of a hash are always strings. But that's ok. Perl will seamlessly convert integers to strings. And it's not necessary here because you're actually using strings ('1'), not integers (1).

%Hash{'1'} = @Array1; 

A couple of errors here. The values in a hash are scalars. So you access them using a scalar sigil ($, not %). And, of course, an array isn't a scalar so you can't store it in a hash value. You can, however, store an array reference in a hash value (as references are scalar values.

$Hash{'1'} = \@Array1; # use \ to get a reference

Alternatively, if you stuck with the [...] version and stored your array reference in $Array_ref, then you can do:

$Hash{'1'} = $Array_ref;

Assign a hash key value to a temporary array

The value in your hash is a reference to your array. So you need to dereference it before storing it in an array variable.

@Temp_Array = @{ $Hash{'1'} };

Delete the first element/item of the temporary array, let's say the numnber "01"'

shift @Temp_Array;

Check if the array has a especifc value, let's say numbers 03 and 09

if (grep { $_ eq '03' } @Temp_Array) {
  say "03 is in the array";
}

Delete especific values from the array, let's say the numnbers 03 and 09

@Temp_Array = grep { $_ ne '03' and $_ ne '09' } @Temp_Array;

Check how many elements/items exist in the array

Simply evaluate the array in a scalar expression.

$num_of_elements = @Temp_Array;

then assign the value back to the hash

Once again, you need to take a reference to the array.

$Hash{'1'} = \@Temp_Array

It's worth pointing out that you don't need to copy the array to a temporary array variable in order to manipulate it. Anywhere that I have used @Temp_Array in the examples above, you can replace it with @{ $Hash{'1'} } and you will be manipulating the array inside the hash directly.

shift @{ $Hash{'1'} }; # for example

I have found many posts that are not helping so much, as they don't talk about long arrays.

That's probably because long arrays and short arrays (and middle-sized arrays) are all handled in exactly the same way in Perl.

Upvotes: 2

goodind1
goodind1

Reputation: 31

By using square brackets for your lists, you've actually created an array reference, which is a scalar. Your assignments should thus be:

my $Array1 = ['01', '02', '03', '04', '09', '10', '11', '12']; 
my $Array2 = ['05', '06', '07', '08', '03', '04', '09'];

etc.

Next, when assigning these references as hash keys, you must use the $ sigil since you're referring to the hash value (a scalar) and not the hash itself.

$Hash{'1'} = $Array1; 
$Hash{'2'} = $Array2; 

Now if you want to assign these references to array variables, you must dereference them:

my @TempArray = @{ $Hash{'1'} };

As for your list of operations/checks on these arrays:

Delete the first item:

shift @TempArray;

Check if a certain value is an element of the array:

my $check = grep { $_ == $some_number } @TempArray;

($check will be the number of matches returned, and thus will evaluate to false if you get zero matches);

Delete an specific element (index unknown) from the array:

Every occurrence of a certain value?

@TempArray = grep { $_ != $some_number } @TempArray;

A specific element (not necessarily first or last)? Need to know the offset.

splice @TempArray => $index;

Check the length of the array:

my $length = @TempArray;

(referring to an array in list context returns its length)

Upvotes: 3

Related Questions