2

I have a question I'm hoping you could help with as I am new to hashes and hash reference stuff?

I have the following data structure:

$VAR1 = {
    'http://www.superuser.com/' => {
        'difference' => {
            'http://www.superuser.com/questions' => '10735',
            'http://www.superuser.com/faq' => '13095'
        },
        'equal' => {
            'http://www.superuser.com/ ' => '20892'
        }
    },
    'http://www.stackoverflow.com/' => {
        'difference' => {
            'http://www.stackoverflow.com/faq' => '13015',
            'http://www.stackoverflow.com/questions' => '10506'
        },
        'equal' => {
            'http://www.stackoverflow.com/ ' => '33362'
        }
    }

If I want to access all the URLs in the key 'difference' so I can then perform some other actions on the URLs, what is the correct or preferred method of accessing those elements?

e.g I will end up with the following URLs that I can then do stuff to in a foreach loop with:

http://www.superuser.com/questions
http://www.superuser.com/faq
http://www.stackoverflow.com/faq
http://www.stackoverflow.com/questions

------EDIT------

Code to access the elements further down the data structure shown above:

my @urls;
foreach my $key1 ( keys( %{$VAR1} ) ) {
    print( "$key1\n" );
    foreach my $key2 ( keys( %{$VAR1->{$key1}} ) ) {
        print( "\t$key2\n" );
    foreach my $key3 ( keys( %{$VAR1->{$key1}{$key2}} ) ) {
        print( "\t\t$key3\n" );
    push @urls, keys %{$VAR1->{$key1}{$key2}{$key3}};
    }
  }
}
print "@urls\n";

Using the code above why do I get the following error?

Can't use string ("13238") as a HASH ref while "strict refs" in use at ....

1 Answer 1

7

It is not difficult, just take the second level of keys off every key in the variable:

my @urls;
for my $key (keys %$VAR1) {
    push @urls, keys %{$VAR1->{$key}{'difference'}};
}

If you're struggling with dereferencing, just keep in mind that all values in a hash or array can only be a scalar value. In a multilevel hash or array the levels are just single hashes/arrays stacked on top of each other.

For example, you could do:

for my $value (values %$VAR1) {
    push @urls, keys %{$value->{'difference'}};
}

Or

for my $name (keys %$VAR1) {
    my $site = $VAR1->{$name};
    push @urls, keys %{$site->{'difference'}};
}

..taking the route either directly over the value (a reference to a hash) or over a temporary variable, representing the value via the key. There is more to read in perldoc perldata.

Sign up to request clarification or add additional context in comments.

7 Comments

thanks that exactly what I was looking for. What would the code look like if i wanted to only access the numbers at the end of every stackoverflow url i.e 13015, 10506 and 33362. I need to learn how to access different parts of the data structure , thanks for your help.
Could you show me what the code would ook like if i wanted to only access the numbers at the end of every stackoverflow url i.e 13015, 10506 and 33362. thanks a lot
@perl-user Its simple. The value of the key 'http://www.stackoverflow.com/' is a hash ref. The keys in that hash ref is 'difference' and 'equal', and their values are also hash refs. The values of those hash refs are the values you are after. Just stack the for loops that way and you'll be fine. Check your results with Data::Dumper if you are unsure what's going on.
Could you take a look at the edit ive added to my question please. Is this how the foreach loops should be done like you mentioned? and also why do I get the error message? thank you very much, you have helped a lot
@perl-user Well, the innermost values are no longer hash references, so you cannot use them as such. You just use the value as it is. By the way, you can make things easier on your eyes if you each loop assign a temporary variable for the particular step in the structure. E.g. for my $key (keys %$VAR1) { my $href1 = $VAR1->{$key}; for my $key2 (keys %$href1) ...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.