Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

How to reference a nested anonymous array

by djw (Vicar)
on May 28, 2002 at 14:00 UTC ( [id://169769]=perlquestion: print w/replies, xml ) Need Help??

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

I have a hash with a nested anonymous hash that holds an anonymous nested array. I have my data in the array and I can access it (print for example) without a problem. I have tried to reference the array, but I think I'm having a problem with syntax because its an anonymous array.


What I can't do is iterate over the array because I don't know how to reference it. Here is some code to show you what is going on:
if (-f) { my $fsize = stat($_)->size; if ($fsize > MINFILESIZE) { open(MD5FILE, "$_") || warn "Can't open file ($_): ($!)\n" +; binmode(MD5FILE); my $md5hash = Digest::MD5->new->addfile(*MD5FILE)->hexdige +st; close(MD5FILE); if (exists($fileInfo{$md5hash})) { $fileInfo{$md5hash}{path}[$fileInfo{$md5hash}{count}] += $File::Find::dir; $fileInfo{$md5hash}{count} += 1; } else { $fileInfo{$md5hash}{filename} = $_; $fileInfo{$md5hash}{size} = $fsize; $fileInfo{$md5hash}{count} = 1; $fileInfo{$md5hash}{path}[0] = $File::Find::dir; } } $totalFiles++; } }
I am using File::Find to search for any duplicate files on a volume of a certain size with the same MD5 sig. I want to track each duplicate file in my hash, and I want to keep the path info for each duplicate in my annonymous array. Using my code above, the correct info gets put into the array and I can even print it out doing this:
print "$fileinfo{$md5hash}{path}[0]\n"; print "$fileinfo{$md5hash}{path}[1]\n"; print "$fileinfo{$md5hash}{path}[2]\n";
This would produce something like:
/home/djw/foo /home/djw/foo/bar /home/djw/foobar
But that assumes I know how many elements are in the array. My question is how do I iterate over the anonymous array?

djw

Replies are listed 'Best First'.
Re: How to reference a nested anonymous array
by Abigail-II (Bishop) on May 28, 2002 at 14:13 UTC
    My question is how do I iterate over the anonymous array?

    That is not very hard. Iterating over an array in Perl is done as follows:

    foreach my $element (@array) { ... }
    But, where ever we write @array, we can replace the array with a block returning a reference to an array - which can be anonymous as well.

    So, in your case, $fileinfo{$md5hash}{path} is a reference to an array. Hence, you can iterate over it like:

    foreach my $element (@{$fileinfo{$md5hash}{path}}) { print $element, "\n"; }

    Abigail

Re: How to reference a nested anonymous array
by Rich36 (Chaplain) on May 28, 2002 at 14:09 UTC

    Try something like:

    foreach(@{ $fileinfo{$md5hash}{path} }) { print; }

    By de-referencing the array, you should be able to treat that array like any other.


    Rich36
(tye)Re: How to reference a nested anonymous array
by tye (Sage) on May 28, 2002 at 15:55 UTC

    Seems like pretty close to this exact question comes up several times each month. Every once in a while I respond to "it" by pointing to References Quick Reference which can be found in Tutorials.

            - tye (but my friends call me "Tye")
Re: How to reference a nested anonymous array
by shelob101 (Sexton) on May 29, 2002 at 03:52 UTC
    One helpful way to think of this problem may be to replace the cumbersome expression
    $fileinfo{$md5hash}{path}
    with a simpler, single scalar. That's what that big ugly thing holds after all, a scalar reference to an anonymous array structure. Something like
    $aref=\@{$fileinfo{$md5hash}{path}}
    would do the trick. Then you can use this scalar reference to your anonymous array like this:
    $aref->[0] $#$aref for $x (@$aref) {...}
    and so on.
    This can be a handy technique sytactically, but also because it reminds you as the programmer what is really stored in those fancy complex data structures like the one you're using. They're just collections of scalar references to other collections, and as such can be passed around as an atomic piece of information. Of course, the correct DE-reference is crucial, but as you can see from above, you can just think of the expression "$aref" as another way of saying "that anonymous array over there". Then things like "$#$aref" (or $#{$aref} if you like) are not so alien.
    Good luck with your data mining. Now just for fun, try adding time-lapse views of your filesystem to this structure :)
    Paul

      Note that

      $aref=\@{$fileinfo{$md5hash}{path}}

      dereferences the array and then creates another reference to it. Preferable might be:

      $aref=$fileinfo{$md5hash}{path}

      i.e., don't dereference the array at all, just assign its reference to a scalar for simplicity, readability and maintainability.

      dmm

      If you GIVE a man a fish you feed him for a day
      But,
      TEACH him to fish and you feed him for a lifetime
Re: How to reference a nested anonymous array
by redemption (Sexton) on May 29, 2002 at 09:03 UTC
    as a newcomer to the Perl way of handling multi-dimensional arrays, hashes of arrays, etc., i found these very useful, esp. perlreftut:
    perlref - http://www.perldoc.com/perl5.6.1/pod/perlref.html
    perlreftut - http://www.perldoc.com/perl5.6.1/pod/perlreftut.html
    _______________
    go SitePoint Forums -> http://sitepointforums.com

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://169769]
Approved by virtualsue
Front-paged by graff
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (6)
As of 2024-03-30 05:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found