Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

two-dimensional arrays

by Ras (Acolyte)
on Aug 08, 2001 at 18:14 UTC ( [id://103049]=perlquestion: print w/replies, xml ) Need Help??

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

Hi everybody, i really need help in using two d arrays.
What i'm trying to do is that i have this arry full of
file names. for example
@array
$array[0] contains eph11.lg
$array[1] contains eph21.lg
$array[2] contains ehp23.lg
$array[3] contains eph31.lg
$array[4] contains eph65.lg
$array[6] contains eph33.lg
$array[7] contains eph66.lg
$array[8] contains eph76.lg
$array[9] contains eph88.lg
                .
                .
                .
    It goes on for a while

If i try and process these file going from the fisrt
index to the last it will take a very long time.
So what i want to do is group a certain a mount of files
together and process them as a group.
The way i group the files is that in a loop
i mod the index of @array with the lenght of @array
and then push that element into a 2d array with the
index of the mod value.
For exampel:
The index
---0-------1------2------3------4--- ---5-------6------7------8------9---
|files1||file2||file3||file4||file5|| file6||file7||file8||file9||file10|

The 2d array:
@2darray
The length + 1 = 10
10%0=0 so put file1 into $2darray[0][0]
10%1=0 so put file2 into $2darray[0][1]
10%2=0 so put file3 into $2darray[0][2]
10%3=1 so put file4 into $2darray[1][0]
10%4=2 so put file5 into $2darray[2][0]
10%5=0 so put file6 into $2darray[0][3]
10%6=4 so put file7 into $2darray[4][0]
10%7=3 so put file8 into $2darray[3][0]
10%8=2 so put file9 into $2darray[2][1]
10%9=1 so put file1 into $2darray[1][1]
10%10=0 so put file1 into $2darray[0][4]

My problem is that i don't know how to do this in perl.
What i'm donig, which doesn't work is:

for($psh_lp=0;$psh_lp<=$len;$psh_lp){
$mod_val = $psh_lp % $len;
push(@group_ary[$mod_val][$phs_lp],$files[$psh_lp]);
}</code>

Can you show me some kind of snytax that can help
me out, thanks in advance.

Replies are listed 'Best First'.
Re: two-dimensional arrays
by c-era (Curate) on Aug 08, 2001 at 18:37 UTC
    Your push statement needs to look like this:
    push (@group_ary[$mod_val],$files[$psh_lp]);
    The way you are trying is creating a 3-d array with each array containing one element.
      Hello

      Type of arg 1 to push must be array (not array slice). You meant: push (@{$group_ary[$mod_val]},$files[$psh_lp]); I know I know, minor stuff.

      Aziz,,,

Re: two-dimensional arrays
by thpfft (Chaplain) on Aug 08, 2001 at 18:44 UTC

    Here's your code in perl:

    push(@{$groups[(($#files + 1) % $_)],$files[$_]) for (0..$#files);

    It's a bit hasty, but that doesn't matter because it won't work anyway. % 0 is an error in perl, not zero.

    But I can't imagine any reason why you would want to do this. It isn't going to speed up loop operations across the whole collection, and it isn't going to help you to identify parts of the collection. The only thing i can think of is that you want to process the collection one chunk at a time, in which case there are much simpler ways to subdivide it.

    Your syntax suggest a javascript or maybe C background. Have a look at perl's hashes (and hashes of hashes): you might be pleasantly surprised.

    But perhaps i've misunderstood. What are you trying to do?<?p>

      You're right thpfft about dividing the group,
      can you show me a better way to subdivide
      Thanks.

        It really depends on what you intend to do with the data later. I'll assume that it's not looping over the whole collection, since the original array is the best way to do that.

        So. On reflection, if you want a set number of groups, then your modulus is as neat a way as any - sorry about that - but it does need to be fixed for the % 0 problem. This one's a bit closer to the format of your original:

        # we have @files my $number_of_files = scalar(@files); my $number_of_groups = 10; my @groups; for (1..$number_of_files) { my $modvalue = $number_of_groups % $_; push @{$groups[$modvalue]},$files[$_ - 1]); }

        but there's always another way. The extra braces just make sure that the $counter goes out of scope when it's no longer needed:

        { my $counter = 0; my $number_of_groups = 10; for (@files) { push(@{$groups[$counter++]},$_); $counter = 0 if ($counter == $number_of_groups); } }

        or if you wanted groups of a fixed size:

        @{groups[$counter++]} = splice(@files,0,$group_size) while @files;

        or maybe 26(ish) groups:

        my %groups; push (@{$groups{substr($_,0,1)}},$_) for @files;

        or perhaps it's more useful to group by suffix?

        for (@files) { my $suffix = (m/\.(\w+)$/) ? $1 : 'none'; push(@{$groups{$suffix}},$_); }

        The last two versions use a hash instead of an array to hold the final collection of groups. The advantage of this is that you can retrieve selected parts directly, without having to scan through the collection again. In the last case, for example, $groups{'jpg'} holds an array of all the files with the suffix .jpg: to get at it you just use

        for (@{$groups{'jpg'}}) { ... }

        Which is only going to be useful if you ever want to present a list of files of a certain type, but in general, if you're going to do all this work i'd say you might as well store the information in a way that adds value by capturing some useful regularity in the collection.

        Incidentally, it just struck me that your objection to the original array was that it took a long time to loop over it. But in order to subdivide it you probably need to loop. Er. Perhaps a better approach is needed earlier on, when the list is first assembled?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-03-28 20:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found