Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a hash to an array

Tags:

I have an array like so,

@switch_ports = () 

and then want to add 50 instances of this hash, to the switch_ports array

%port = (data1 => 0, data2 => 0, changed => 0) 

however, if I push my hash to the array

push(@switch_ports, %port) 

but if I do print @switch_ports I just see

data10data20changed0 

so it just seems to be added them to the array, (joining them) and if I try and loop the array and print the keys, it also fails.

I think i am going retarded from smashed my head into the desk so hard.

1 - Can you store a hash in an array?

2 - Can you have an array of hashes?

Trying to get...

switchports     0         data1         data2         changed     1         data1         .... 

thus

foreach $port (@switchport) {     print $port['data1'] } 

would return all of the data1 for all of the hashes in the array.

Yes, I fail at Perl

like image 303
Wizzard Avatar asked Nov 27 '11 00:11

Wizzard


People also ask

Can you hash an array?

While an array can be used to construct hash tables, array indexes its elements using integers. However, if we want to store data and use keys other than integer, such as 'string', we may want to use dictionary. Dictionaries in Python are implemented using hash tables.

How do you create an array of hashes?

Creating an array of hashes You are allowed to create an array of hashes either by simply initializing array with hashes or by using array. push() to push hashes inside the array. Note: Both “Key” and :Key acts as a key in a hash in ruby.

How do you push a hash array?

To append a new value to the array of values associated with a particular key, use push : push @{ $hash{"a key"} }, $value; The classic application of these data structures is inverting a hash that has many keys with the same associated value. When inverted, you end up with a hash that has many values for the same key.

How do you hash an array in Ruby?

In Ruby, a hash is a collection of key-value pairs. A hash is denoted by a set of curly braces ( {} ) which contains key-value pairs separated by commas. Each value is assigned to a key using a hash rocket ( => ). Calling the hash followed by a key name within brackets grabs the value associated with that key.


2 Answers

In Perl, array and hash members must be a single value. Before Perl 5.0, there was no (easy) way to do what you want.

However, in Perl 5 you can now use a reference to your hash. A reference is simply the memory location where the item is being stored. To get a reference, you put a backslash in front of the variable:

use feature qw(say);  my $foo = "bar"; say $foo;    #prints "bar" say \$foo;   #prints SCALAR(0x7fad01029070) or something like that 

Thus:

my @switch_ports = (); my %port = ( data1 => 0, data2 => 0, changed => 0 ); my $port_ref = \%port;  push( @switch_ports, $port_ref ); 

And, you don't have to create $port_ref:

my @switch_ports = (); my %port = ( data1 => 0, data2 => 0, changed => 0 );  push( @switch_ports, \%port ); 

To get the actual value of the reference, simply put the symbol back on front:

#Remember: This is a REFERENCE to the hash and not the hash itself $port_ref = $switch_ports[0]; %port = %{$port_ref};      #Dereferences the reference $port_ref;  print "$port{data1}  $port{data2}  $port{changed}\n"; 

Another shortcut:

%port = %{$port[0]};   #Dereference in a single step print "$port{data1}  $port{data2}  $port{changed}\n"; 

Or, even shorter, dereferencing as you go along:

print ${$port[0]}{data1} . " " . ${$port[0]}{data2} . " " . ${$port[0]}{changed} . "\n"; 

And a little syntactic sweetener. It means the same, but is easier to read:

print $port[0]->{data1} . " " . $port[0]->{data2} . " " . $port[0]->{changed} . "\n"; 

Take a look at Perldoc's perlreftut and perlref. The first one is a tutorial.

like image 125
David W. Avatar answered Sep 21 '22 14:09

David W.


When you try:

%port = (data1 => 0, data2 => 0, changed => 0); push @switch_ports, %port; 

What really happens is:

push @switch_ports, "data1", 0, "data2", 0, "changed", 0; 

Because arrays and hashes will automatically break into their elements when used in list context.

When you want to create 50 instances of a hash, it is not a good idea to use a reference to an existing hash as others have suggested, as that will only create 50 different references to the same hash. Which will crash and burn for obvious reasons.

What you need is something like:

push @array, { data1 => 0, data2 => 0, changed => 0 } for 1 .. 50; 

Which will add 50 unique anonymous hashes to the array. The braces denotes construction of an anonymous hash, and returns a scalar reference to it.

ETA: Your example of how to access this data is wrong.

foreach $port (@switchport) {     print $port['data1'];    # will use @port, not $port } 

Using a subscript on a scalar variable will attempt to access an array in that namespace, not a scalar. In perl, it is valid to have two separate variables $port and @port. Brackets are used for arrays, not hashes. When using references, you also need to use the arrow operator: $port->{data1}. Hence:

for my $port (@switchport) {     print $port->{data1}; } 
like image 42
TLP Avatar answered Sep 20 '22 14:09

TLP