Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Associative array

by gem555 (Acolyte)
on Jul 13, 2009 at 06:13 UTC ( #779467=perlquestion: print w/replies, xml ) Need Help??

gem555 has asked for the wisdom of the Perl Monks concerning the following question:

I have a hash. When I loop the hash as below: All the key and values are listed. There is a key called 'correct'. How can I print only the key "correct".
for my $data_pair (@data_list) { print "The value is $data_pair->{'correct'}\n"; }
This gives the value is unitialized. warning message. I want to print the values for the key "correct". Please help me

Replies are listed 'Best First'.
Re: Associative array
by moritz (Cardinal) on Jul 13, 2009 at 06:17 UTC

    You're using $data_pair as if it were a hash reference (see perlreftut), and you use the correct syntax for that. If you get an undefined warning, maybe the value simply doesn't exist?

    Update: changed content. I didn't see the hash ref on first reading.

      the below code prints out the keys and values
      print $data_pair->{'key'}; print $data_pair->{'value'};
        This doesn't print the keys and values, but the values associated with the keys key and value.

        If you want to print the hash out for debugging purposes, use Data::Dumper.

        If you want to access the keys/values in your program, use keys %{$data_pair} or values %{$data_pair} instead.

Re: Associative array
by Polyglot (Pilgrim) on Jul 13, 2009 at 06:29 UTC
    It looks to me like you are trying to do two mutually exclusive things at the same time: print multiple values and print just one value. You have used a "for" loop as if you were going to print every value, but then only want to print the "correct" one.

    Could it be that the "correct" value is not the first one in the list, and that the first value looked at (not necessarily a "correct" one) is uninitialized?



Re: Associative array
by ELISHEVA (Prior) on Jul 13, 2009 at 06:50 UTC

    Perl hashes are not associative arraysassociation lists, though I can see how one might think that way if one comes from a Lisp background. Please take a careful look at perldata and perldsc for a better understanding of Perl hashes and how to work with them.

    How did you set up @data_list? The code above would only print out a value if you had set up @data_list something like this:

    my @data_list = ( { correct => 42 } );

    Or maybe you did something like this: my %data_list =(correct=>42)? That does not set up a collection of data pairs even though the fat comma (=>) may make it seem that way. To iterate through the elements of %data_list using a for loop one would need to use keys and do something like this:

    foreach my $k (keys %data_list) { my $v = $data_list->{$k}; print "The value for $k is $v\n"; }

    @data_list=(correct => 42) doesn't set up discrete pairs either. It merely sets up a flat array with alternating keys and values. To iterate through key value pairs for @data_list one would need to do something like this:

    for (my $i=0; $i < $#data_list; $i+=2) { my $k = $data_list[$i]; my $v = $data_list[$i+1]; print "The value for $k is $v\n"; }

    Note that in Perl, %data_list and @data_list are two entirely different variables. If the preceding discussion does not clarify things, I think you will need to post more code so we can see how @data_list and/or %data_list is set up.

    Best, beth

    Update - struck out "associative array" and replaced with "association list" - see Re^5: Associative array for explanation.

      Perl hashes are not associative arrays,

      Perhaps you could explain what you see as the difference? (Cos a lot of people are happy to refer to Perl's hashes as 'associative arrays'.)

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Indeed. I put this somewhere in the same category as "lists in scalar context". It fits the orthography and good luck trying to get people to see differently. However, if one views a hash as an associative array one is likely to end up in all sorts of confusion, especially if one is first familiar with Lisp.

        Two of the most important sources of confusion are: (a) confusion of implementation with concept and (b) confusion over ordering.

        The name "associative array" confuses an implementation of a hash with the concept of a hash. Conceptually, a Perl hash is a data structure that will allow one to retrieve a value by name rather than position. There are many ways to implement this. For example, in Lisp there are two different ways to get hash-like effects: alists and plists.

        • alists (association lists) are written like this: ((rose . red) (lily . white) (buttercup . yellow)). The Perl equivalent would be (['rose','red'],['lily','white'], ['buttercup', 'yellow']). This is clearly something quite different from what is meant in Perl by a hash. See Association Lists
        • plists (property lists) are written like this: (rose red lily white buttercup yellow lily white). The Perl equivalent would be written nearly identically:qw(rose red lily white buttercup yellow lily white). But again, this is not what Perl considers as a hash. It is merely an alternating sequence of keys and values. See Property Lists

        In many other languages, Perl included, hashes (sometimes referred to as dictionaries) are implemented using data structures that are much more complicated than either a-lists or p-lists. Perl in fact has two entirely different C structures for hashes (HV) and arrays (AV). Although both have ARRAY, FILL, and MAX to describe their memory usage, the similarity stops there. The HV structure is carefully organized to maximize the speed with which values can be retrieved by property name and to conserve storage (in some cases keys are stored as pointers to a shared set of keys rather than having their own private string representation). See PerlGuts Illustrated.

        Now, I suppose you could argue that even Perl stores key-value pairs in its ARRAY member and that makes it an associative array. However, that is a misleading oversimplification. And it brings us to the next issue: ordering.

        Another problem with viewing hashes as associative arrays is that an array has an explicit ordering to its elements, whether those elements are simple scalars or key-value pairs. Hashes, by contrast, have an undefined unordering. Failing to grasp the distinction can cause serious problems, including hard to track intermittent bugs. One who views a hash as an associative array is likely to assume that ordering of hash members is consistent between runs of programs and may perhaps base their program on that assumption. However, this is a dangerous assumption. Perl hashes have an unpredictable order by intent. One of the techniques to safeguard software from algorithmic complexity attacks is to randomize the order of hash keys, thus making it harder to find a predictable spot to insert dangerous code. See keys and perlsec for further discussion.

        Best, beth

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://779467]
Approved by ELISHEVA
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2020-11-28 06:19 GMT
Find Nodes?
    Voting Booth?

    No recent polls found