http://www.perlmonks.org?node_id=1012264

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

Hi monks, i'm trying to get my head around some more complicated data structures and i'm wondering how best to represent my data.

I hope i explain this ok but basically i have the following:

my @user_file_part1=(); my @user_file_part2=(); my @user_file_part3=(); my @test_file_part1=(); my @test_file_part2=(); my @test_file_part3=(); my @trim_file_part1=(); my @trim_file_part2=(); my @trim_file_part3=(); my @user_file=(\@user_file_part1, \@user_file_part2, \@user_file_part3); my @test_file=(\@test_file_part1, \@test_file_part2, \@test_file_part3); my @trim_file=(\@trim_file_part1, \@trim_file_part2, \@trim_file_part3); my %main_file=( USER <= \@user_file, TEST <= \@test_file, TRIM <= \@trim_file, );

So i have a hash of arrays of arrays if that makes sense (my brain is mush now!)

So my question after all that is, how can i better represent the above code? Do i have to make the array declarations before i take their reference or can i do that at the same time?

Also, if i wanted to push a value onto one of the end arrays, i.e. @user_file_part1, how would i reference it?

Like this?

push(@{$main_file{"USER"}[0]}, $string);

Thanks in advance!

Replies are listed 'Best First'.
Re: How to better represent a complex data structure.
by BrowserUk (Patriarch) on Jan 08, 2013 at 16:19 UTC
    Do i have to make the array declarations before i take their reference or can i do that at the same time?

    You do not need to declare (or even name) the arrays at all.

    When you push or assign to a complex data structure the intermediate aggregates will be autovivified (Ie. created if they do not yet exist.):

    my %main_file; push @{ $main_file{ USER }[ 1 ] }, 'fred'; push @{ $main_file{ TEST }[ 3 ] }, 'bill'; push @{ $main_file{ TRIM }[ 0 ] }, 'john'; pp \%main_file;; { TEST => [undef, undef, undef, ["bill"]], TRIM => [["john"]], USER => [undef, ["fred"]], }

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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.

      Thanks!

Re: How to better represent a complex data structure.
by choroba (Cardinal) on Jan 08, 2013 at 16:10 UTC
    Fortunately, you do not have to make all the declarations. You can use anonymous arrays (and hashes):
    my %main_file = ( USER => [ [], [], [] ], TEST => [ [], [], [] ], TRIM => [ [], [], [] ], );
    If all the arrays are empty at the beginning, you do not have to declare anything - everything will be autovivified when dereferenced. So, in short:
    my %main_file; push @{ $main_file{USER}[0] }, $string;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Thanks! I was hoping that would be the case

      I'm still reading about autovivication and i was a little confused by it!

Re: How to better represent a complex data structure.
by muba (Priest) on Jan 08, 2013 at 16:26 UTC
    my %main_file=( USER <= \@user_file, TEST <= \@test_file, TRIM <= \@trim_file, );

    Obviously you mean => there ;)

    Like this?
    push(@{$main_file{"USER"}[0]}, $string);

    Have you tried it? Did it fail you?

    > perl -Mstrict -MData::Dumper -wE ' my %main_file = ( USER => [ [], [], [] ] ); push @{$main_file{"USER"}[0]}, "string ;)"; print Dumper \%main_file; ' $VAR1 = { 'USER' => [ [ 'string ;)' ], [], [] ] }; >

      I have tried it roughly, but the mess of code i wrote quickly grew out of hand so i wrote the above to try to simplify it in my head and to simplify the question!

      Thanks for you reply.

Re: How to better represent a complex data structure.
by sundialsvc4 (Abbot) on Jan 08, 2013 at 20:02 UTC

    Always bear in mind that Perl is a pragmatic language, built “out of necessity”   Lots of people (from “Larry Wall, himself” on forward) have faced the same problems that you did, and developed a pragmatic way to solve them.

    In (this | your | their) case, the “magic pixie dust” is called references.   The apparent “complexity” of your situation in-fact arises from the fact that you need to insert “a complex data-structure” into one and only one place.   This requirement is very elegantly (and very completely ...) handled by the singular notion of “a reference,” which is:   “a single thing” (i.e. it can exist “in one place”) that can refer to (ommmm.....) anything-at-all.   (Furthermore, you can have any number of references to the selfsame thing ... so it can be in more than one place at the same time, if you so desire.)

    The next key to this puzzle is ... that you can express this key notion without a bunch of extra steps.   In other words, without declaring a bunch of extra, otherwise-unnecessary variables.   Instead of “first” declaring @whatever and then later referring to \@whatever, you can simply describe what you really want, in one pragmatic step, and Perl will understand.

    The Perl language is, after all, a human tool, that was originally conceived by someone who “had a job to ‘get done’,” and who devised the most-straightforward (to him... at the time ...) way, by which he could persuade a digital computer(!!) to do it.   (And hundreds if not thousands of other kindred souls, faced in their turn with the selfsame objective, have surely labored upon it since.)

    Fact is... “Representing a complex data structure” is par for the course to every single one of us, from Larry Wall on down.   We’ve gotten very good at it.   ;-)

      “had a job to ‘get done’,”
      Awesome indeed. While quietly admiring your thoughtful placement of eleven pairs of “unnecessary quotes,” I was stunned by the inspired and original composition shown above: a pair of unnecessary single quotes embedded in a pair of unnecessary double quotes with a “chicago-manual-of-style” comma and some unnecessary typography thrown in for good measure! Well done.

      Awesome reply! Thanks! I'll keep it in mind!