简体   繁体   中英

Perl array reference containing the number of keys in a hash, not the actual keys

There is a twist obviously. When I do it like that it works and contains all the keys:

my $hash = {};
$$hash{1} = "asd";
$$hash{21} = "fafafa";

for my $key (keys($hash))
{
    push($arr_ref, $key);
}

print Dumper($arr_ref);

However when I try to do it the following way I only get the number of the keys:

    my $hash = {};
    $$hash{1} = "asd";
    $$hash{21} = "fafafa";
    my $arr_ref = [];
    $arr_ref = keys($hash);

In my head both things should be the same and after all if I do it like that:

my @arr = keys($hash);

@arr will contain the keys of the hash. The question is where is the difference ?

use strict; would be helpful along with use warnings; , try

@$arr_ref = keys($hash);

as $arr_ref = keys($hash); is implicit version of $arr_ref = scalar keys($hash); and ensures scalar context in both cases.

Also notice that keys $scalar is experimental , and keys %$scalar is advised.

You have a few things confused here. If the sigil (the sign in front of the var name) is a $ , you have a scalar value.

Here is a list of things you need to remember:

  • Both $hash and $arr_ref are references, so the variable names have a $ because they only store a memory address reference to where the actual hash/array is.
  • An array has a @ sigil, and a hash has a % sigil. So @array and %hash are both not references.
  • If you want to put a data structure into another data structure in Perl, you need to reference it. This is done by putting a \\ in front of the variable name like $ref = \\@array .
  • An array gets a list assigned: my @colors = ( 'red', 'green' );
  • A hash gets a list (with parenthesis) assigned: %count = ( 'red' => 5, 'green' => 2 );
  • To access a hash value, use $count{'red'} . The sigil changes to $ because the value behind the whole identifier count{'red'} is now a scalar value.
  • To access an array value, use $colors[0] (which will give 'red' .
  • The keys function returns a list.
  • Forcing a list or an array into scalar context will give its number of elements.

Now with all this knowledge you will see that when you assign keys($hash) to $arr_ref , you are forcing scalar context, thus you get the count.

  • If you want an array of the keys, use my @array = keys($hash) .
  • If you want an array ref, use my $arr_ref = \\keys($hash) or put the list that is returned by keys into an array ref like my $arr_ref = [ keys($hash) ] .

Also note that Perl's keys built-in only recently learned to handle references. You should be giving it a hash, or dereference your hash ref like keys( %{ $hash_ref } ) . This can be shortened to keys %$hash_ref .

Also, always use strict and use warnings as both will help you by telling you about things you did wrong or things that you might have gotten confused.


To illustrate some more, I have rewritten your first piece of code to three different forms.

No references:

use strict; 
use warnings;
use Data::Dumper;

my %hash = (
  1  => "asd",
  21 => "fafafa"
);

my @array_of_keys = ();
for my $key ( keys %hash )
{
  push @array_of_keys, $key;
}

print Dumper( \@array_of_keys ); # reference the array because it looks nicer in Dumper

Reference for the array:

use strict; 
use warnings;
use Data::Dumper;

my %hash = (
  1  => "asd",
  21 => "fafafa"
);

my $arrayref_of_keys = [];
for my $key ( keys %hash )
{
  push @$arrayref_of_keys, $key; # or @{ $foo }
}

print Dumper( $arrayref_of_keys ); # it's already a ref, so no need for \

All references:

use strict; 
use warnings;
use Data::Dumper;

my %hashref = {    # notice the curly braces instead of round parens
  1  => "asd",
  21 => "fafafa"
};

my $arrayref_of_keys = [];
for my $key ( keys %$hashref )   # or %{ $foo }
{
  push @$arrayref_of_keys, $key; # or @{ $foo }
}

print Dumper( $arrayref_of_keys );

I suggest you read perlref and perlreftut .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM