in reply to two-dimensional arrays

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>

Replies are listed 'Best First'.
Re: Re: two-dimensional arrays
by Ras (Acolyte) on Aug 08, 2001 at 19:00 UTC
    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?