Help with sorting lists of lists

C

Chris Weisiger

I apologize if this is the wrong place to post this; please let me know
the proper target if so.

I have a list of lists of numbers, and I want to sort the sublists.
Every variant on the syntax that I've tried either doesn't visibly do
anything to sort the lists, or else undefines them all. Here's what I
originally tried:

for (my $i = 0; $i < $numActors; ++$i)
{
for (my $j = 0; $j < $actors[$i]; ++$j)
{
$prolls[$i][$j] = int (rand(20) + 1);
} }
@prolls[$i] = sort {$a <=> $b} @prolls[$i];
} }

I suspect that I'm getting tripped up by how Perl handles lists of
lists and references and all that, but all the searching I've done
hasn't turned up anything that's worked. Any help would be appreciated.

For reference, I'm working on a dice rolling program for the Donjon
tabletop RPG. It's a great system, but it needs a lot of d20s...
 
A

A. Sinan Unur

I have a list of lists of numbers, and I want to sort the
sublists.
Every variant on the syntax that I've tried either doesn't visibly do
anything to sort the lists, or else undefines them all. Here's what I
originally tried:

for (my $i = 0; $i < $numActors; ++$i)

Life is generally easier without C-style loops.
{
for (my $j = 0; $j < $actors[$i]; ++$j)
{
$prolls[$i][$j] = int (rand(20) + 1);
} }
@prolls[$i] = sort {$a <=> $b} @prolls[$i];

You should

use strict;

and

use warnings;

What you probably want to do is set the $i th element of @prolls to a
reference to the sorted array: i.e. (untested)

$prolls[$i] = [ sort { $a <=> $b } @{ $prolls[$i] } ];

Since you did not post a self-contained script that I could run (why not?),
I am not sure this would solve your problem. Take a look at

perldoc perlreftut

#! perl

use strict;
use warnings;

my @lol = (
[ 3, 7, 4, 5 ],
[ 11, 15, 1, 3, 5 ],
[ 2, 1, -1, 3, 4, 5, 9, 22, 11 ],
);

for (@lol) {
$_= [ sort {$a <=> $b} @{ $_ } ];
}

use Data::Dumper;
print Dumper \@lol;
__END__

Sinan
 
C

Chris Weisiger

Life is generally easier without C-style loops.

Probably; my style is in general not that good since it's a mishmash of
C styles and Perl styles.
You should

use strict;

and

use warnings;

Done and done, as a matter of course.
What you probably want to do is set the $i th element of @prolls to a
reference to the sorted array: i.e. (untested)

$prolls[$i] = [ sort { $a <=> $b } @{ $prolls[$i] } ];

And this does the trick. Thank you very much. I'm still not certain
exactly what is going on here, but at least the code works.
Since you did not post a self-contained script that I could run (why
not?), I am not sure this would solve your problem. Take a look at

perldoc perlreftut

Strange that perldoc.com didn't come up in my copious Google searching.
I'll keep it bookmarked. Again, thanks.
 
A

A. Sinan Unur

Strange that perldoc.com didn't come up in my copious Google
searching.

No need to venture out to the whole world wide web. You can access the Perl
documentation installed on your computer using this command from the shell
you are using.

To see the available documentation, type

perldoc perltoc

on the command line.

Sinan.
 
E

Eric Schwartz

Chris Weisiger said:
$prolls[$i] = [ sort { $a <=> $b } @{ $prolls[$i] } ];

And this does the trick. Thank you very much. I'm still not certain
exactly what is going on here, but at least the code works.

Cargo-cult programming, even when the source is a Respected Regular,
is always bad. So let's take a look at what's going on, shall we?

Well, you know what this is, I hope, so we'll skip to the right-hand side.
[ sort { $a <=> $b } @{ $prolls[$i] } ]

[ something ] returns a reference to an anonymous array that contains
the list 'something'. By that, we know two things:

1) $prolls[$i] will contain a reference to an anonymous array, and
2) sort { $a <=> $b } @{ $prolls[$i] } is a list, or at the very least
will be interpreted in list context.

Okay, given that, we're almost done, but since I'm taking baby steps
already, I'll continue for the benefit of the peanut gallery. If you
look up the documentation for 'sort' (via: 'perldoc -f sort' at the
command line), you will see that one of its forms is

sort BLOCK LIST

I'll leave reading sort's documentation to you, Dear Reader, but the
clear implication of this is that

is a block, and

is a list. This is further confirmed by the fact that @{ something }
is one way to dereference a reference to an array, and get that array
back. This is documented in perlref.pod; read it NOW, via 'perldoc
perlref' at the command line.

As a consequence of THAT, we know that $prolls[$i] is an arrayref,
which is convenient, because if you look back up to the top of this
message, I showed that we are assigning an arrayref back to
$prolls[$i].

Does that make sense?

-=Eric
 
S

Shawn Corey

A. Sinan Unur said:
No need to venture out to the whole world wide web. You can access the Perl
documentation installed on your computer using this command from the shell
you are using.

To see the available documentation, type

perldoc perltoc

on the command line.

Sinan.

The problem with perldoc is its lack of adequate searching. perldoc -q
keyword_guess only searches the FAQs. http://www.perldoc.com/ is more
extensive but like all searches, you have to guess the magic password to
open the Cave of Riches.

--- Shawn
 
A

Anno Siegel

Shawn Corey said:
The problem with perldoc is its lack of adequate searching. perldoc -q
keyword_guess only searches the FAQs. http://www.perldoc.com/ is more
extensive but like all searches, you have to guess the magic password to
open the Cave of Riches.

Direct grep is primitive, but efficient. Go to where the pods are:

eval set `perl -V:privlib`
cd $privlib/pod # or $privlib/pods, the name has changed recently

grep -li 'frobnitzer'

That will list all Perl documents that mention "frobnitzer". Vary
to taste. Modify appropriately for non-Unix systems.

Anno
 
T

Tad McClellan

The problem with perldoc is its lack of adequate searching.


Use something else for searching then.

Any OS worth its salt can easily search in the *.pod files for you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top