Sort array of objects using a method

M

Marcus

Hello, I'am a newbee in Perl and in Newsgroups. But I hope for some
help.

I have a array of Objekts and i want to sort these Objekts by using a
Objektmethod.

I tried this:
certainly the Objektstore ist filled with Objekts !!!

@unsortedObjektstore

@sortedObjekts = sort {$unsortedObjektstore->getNumber() <=>
$unsortedObjektstore->getNumber()} @unsortedObjektstore;

I thougt it works like an example in perldoc:
# sort numerically descending
@articles = sort {$b <=> $a} @files;

But it don't do so.
Can somebody help me?
 
U

Uri Guttman

M> Hello, I'am a newbee in Perl and in Newsgroups. But I hope for some
M> help.

M> I have a array of Objekts and i want to sort these Objekts by using a
M> Objektmethod.

M> I tried this:
M> certainly the Objektstore ist filled with Objekts !!!

M> @unsortedObjektstore

M> @sortedObjekts = sort {$unsortedObjektstore->getNumber() <=>
M> $unsortedObjektstore->getNumber()} @unsortedObjektstore;

where did $unsortedObjektstore get its value? sort doesn't put it there.

M> I thougt it works like an example in perldoc:
M> # sort numerically descending
M> @articles = sort {$b <=> $a} @files;

so do the same as sort. note that $a and $b are special variable that
sort uses to assign pairs of values to be compared. your code assumed
your own variable name which is wrong.

so use use $a and $b as the objects and call your methods like you did:

@sortedObjekts = sort { $a->getNumber() <=> $b->getNumber()}
@unsortedObjektstore;

uri
 
T

Tassilo v. Parseval

Also sprach Uri Guttman:
M> Hello, I'am a newbee in Perl and in Newsgroups. But I hope for some
M> help.

M> I have a array of Objekts and i want to sort these Objekts by using a
M> Objektmethod.

M> I tried this:
M> certainly the Objektstore ist filled with Objekts !!!

M> @unsortedObjektstore

M> @sortedObjekts = sort {$unsortedObjektstore->getNumber() <=>
M> $unsortedObjektstore->getNumber()} @unsortedObjektstore;

where did $unsortedObjektstore get its value? sort doesn't put it there.

M> I thougt it works like an example in perldoc:
M> # sort numerically descending
M> @articles = sort {$b <=> $a} @files;

so do the same as sort. note that $a and $b are special variable that
sort uses to assign pairs of values to be compared. your code assumed
your own variable name which is wrong.

so use use $a and $b as the objects and call your methods like you did:

@sortedObjekts = sort { $a->getNumber() <=> $b->getNumber()}
@unsortedObjektstore;

A good moment to also mention one of the transforms as I wouldn't want
to call two methods n*log(n) times. Schwartzian transform comes to mind
(hmmh, Guttman-Rosler can't be used on objects, can it?):

@sortedObjects = map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map { [ $_->getNumber, $_ ] } @sortedObjects;

Tassilo
 
M

Marcus

Uri Guttman said:
M> Hello, I'am a newbee in Perl and in Newsgroups. But I hope for some
M> help.

M> I have a array of Objekts and i want to sort these Objekts by using a
M> Objektmethod.

M> I tried this:
M> certainly the Objektstore ist filled with Objekts !!!

M> @unsortedObjektstore

M> @sortedObjekts = sort {$unsortedObjektstore->getNumber() <=>
M> $unsortedObjektstore->getNumber()} @unsortedObjektstore;

where did $unsortedObjektstore get its value? sort doesn't put it there.

M> I thougt it works like an example in perldoc:
M> # sort numerically descending
M> @articles = sort {$b <=> $a} @files;

so do the same as sort. note that $a and $b are special variable that
sort uses to assign pairs of values to be compared. your code assumed
your own variable name which is wrong.

so use use $a and $b as the objects and call your methods like you did:

@sortedObjekts = sort { $a->getNumber() <=> $b->getNumber()}
@unsortedObjektstore;

uri

Hey, it works.
The hint with the special variable was the key.
Thanks a lot.

-Marcus
 
A

Anno Siegel

[sorting, the Schwartzian transform]
(hmmh, Guttman-Rosler can't be used on objects, can it?):

No, not directly. It relies on the ability to retrieve the original
element through a substr() operation. To do that with references would
require extra means, like accessing an auxiliary array or hash.

Let's see:

w = \ qw( 4 2 7 5 9 12 6); # raw is a list of scalar refs

my $size = 16;
my @sorted = map $raw[ substr( $_, $size)],a # retrieve originals
sort # default string sort
map sprintf( "%${size}s%d", ${ $raw[ $_]}, $_),# build sortable strings
0 .. $#raw;

print "$$_\n" for @sorted;

Ah, hat doesn't look half bad. It preserves the essential of the GRT,
default sorting, and the only extra cost is another access to the
original array (okay, and indexed access when the strings are built).
Is that still GRT? Uri?

Anno
 
A

Anno Siegel

[sorting, the Schwartzian transform]
(hmmh, Guttman-Rosler can't be used on objects, can it?):

No, not directly. It relies on the ability to retrieve the original
element through a substr() operation. To do that with references would
require extra means, like accessing an auxiliary array or hash.

Let's see:

w = \ qw( 4 2 7 5 9 12 6); # raw is a list of scalar refs

my $size = 16;
my @sorted = map $raw[ substr( $_, $size)], # retrieve originals
sort # default string sort
map sprintf( "%${size}s%d", ${ $raw[ $_]}, $_),# build sortable strings
0 .. $#raw;

print "$$_\n" for @sorted;

Ah, hat doesn't look half bad. It preserves the essential of the GRT,
default sorting, and the only extra cost is another access to the
original array (okay, and indexed access when the strings are built).
Is that still GRT? Uri?

Anno
 
A

Anno Siegel

[sorting, the Schwartzian transform]
(hmmh, Guttman-Rosler can't be used on objects, can it?):

No, not directly. It relies on the ability to retrieve the original
element through a substr() operation. To do that with references would
require extra means, like accessing an auxiliary array or hash.

Let's see:

w = \ qw( 4 2 7 5 9 12 6); # raw is a list of scalar refs

my $size = 16;
my @sorted = map $raw[ substr( $_, $size)], # retrieve originals
sort # default string sort
map sprintf( "%${size}s%d", ${ $raw[ $_]}, $_),# build sortable strings
0 .. $#raw;

print "$$_\n" for @sorted;

Ah, that doesn't look half bad. It preserves the essential of the GRT,
default sorting, and the only extra cost is another access to the
original array (okay, and indexed access when the strings are built).
Is that still GRT? Uri?

Anno
 
U

Uri Guttman

TvP> A good moment to also mention one of the transforms as I wouldn't want
TvP> to call two methods n*log(n) times. Schwartzian transform comes to mind
TvP> (hmmh, Guttman-Rosler can't be used on objects, can it?):

the GRT can be used on a list of objects or refs. you preprocess the
list to make the key strings and then append a sequence number. you sort
that and extract the sequence number and index with that back into the
original list. this is covered in the sort paper.

uri
 
U

Uri Guttman

AS> No, not directly. It relies on the ability to retrieve the original
AS> element through a substr() operation. To do that with references would
AS> require extra means, like accessing an auxiliary array or hash.

AS> Let's see:

AS> w = \ qw( 4 2 7 5 9 12 6); # raw is a list of scalar refs

AS> my $size = 16;
AS> my @sorted = map $raw[ substr( $_, $size)],a # retrieve originals
AS> sort # default string sort
AS> map sprintf( "%${size}s%d", ${ $raw[ $_]}, $_),# build sortable strings
AS> 0 .. $#raw;

AS> print "$$_\n" for @sorted;

AS> Ah, hat doesn't look half bad. It preserves the essential of the GRT,
AS> default sorting, and the only extra cost is another access to the
AS> original array (okay, and indexed access when the strings are built).
AS> Is that still GRT? Uri?

i would say it is. the main point of the GRT is to call sort with no
comparison block. all the various techniques used to make that happen
all fall under the same GRT umbrella IMNSHO. :)

my coauthor (larry rosler) would prefer to use pack instead of sprintf
and use a binary 4 byte sequence field and also binary formats for the
real keys. it makes for a shorter key which makes for a faster
comparison. i don't think i ever benchmarked pack vs sprintf in the GRT.

uri
 
U

Uri Guttman

M> Hey, it works.
M> The hint with the special variable was the key.

it wasn't a hint, it was a full answer. now please rtfm on sort and
learn about $a and $b.

uri
 
A

Anno Siegel

Uri Guttman said:
AS> No, not directly. It relies on the ability to retrieve the original
AS> element through a substr() operation. To do that with references would
AS> require extra means, like accessing an auxiliary array or hash.

AS> Let's see:

AS> w = \ qw( 4 2 7 5 9 12 6); # raw is a list of scalar refs

AS> my $size = 16;
AS> my @sorted = map $raw[ substr( $_, $size)],a # retrieve
originals
AS> sort # default
string sort
AS> map sprintf( "%${size}s%d", ${ $raw[ $_]}, $_),# build
sortable strings
AS> 0 .. $#raw;

AS> print "$$_\n" for @sorted;

AS> Ah, hat doesn't look half bad. It preserves the essential of the GRT,
AS> default sorting, and the only extra cost is another access to the
AS> original array (okay, and indexed access when the strings are built).
AS> Is that still GRT? Uri?

i would say it is. the main point of the GRT is to call sort with no
comparison block. all the various techniques used to make that happen
all fall under the same GRT umbrella IMNSHO. :)

Well, that's how it works, isn't it? :)
my coauthor (larry rosler) would prefer to use pack instead of sprintf
and use a binary 4 byte sequence field and also binary formats for the
real keys. it makes for a shorter key which makes for a faster
comparison. i don't think i ever benchmarked pack vs sprintf in the GRT.

"Sprintf" and "pack/unpack" are comparatively slow functions, for similar
reasons: the do a run-time interpretation of a format string. One would
probably want to factor them out to see the influence of key length on
sorting efficiency.

Another variant is to use an array slice to put the final sorted list
together: "@raw[ map substr( $_, ...), sort ... ]". It's less readable,
imo, so to be acceptable it would have to be faster, which I doubt.

Anno
 
U

Uri Guttman

AS> Ah, hat doesn't look half bad. It preserves the essential of the GRT,
AS> default sorting, and the only extra cost is another access to the
AS> original array (okay, and indexed access when the strings are built).
AS> Is that still GRT? Uri?
AS> Well, that's how it works, isn't it? :)

well you asked it is GRT and i said it was!

this got me thinking about my long delayed GRT module. i had started one
about the time i co-wrote the paper but it got shelved early on. so
today i had a flash about making it much simpler. i had previously
wanted to have a specification for how to extract each sort key from the
record. but the flash was to just have the user supply the perl code for
that (assuming the record is in $_). this removes much of the complexity
of the module and allows it to focus on making the GRT combined key and
to not need code for key extractions (which can be very complex). in my
next batch of tuits, i may go back to this module and do it this way. i
think the name would be Sort::GRT (it was to be Sort::Records). there is
a Sort::Fields module but it only handles string records i think.

AS> "Sprintf" and "pack/unpack" are comparatively slow functions, for similar
AS> reasons: the do a run-time interpretation of a format string. One would
AS> probably want to factor them out to see the influence of key length on
AS> sorting efficiency.

they also can do different things with regard to the keys. i think
floats have to be compared in binary format (we never came up with a
satisfactory string format that was easy to generate).

AS> Another variant is to use an array slice to put the final sorted list
AS> together: "@raw[ map substr( $_, ...), sort ... ]". It's less readable,
AS> imo, so to be acceptable it would have to be faster, which I doubt.

that is a good point. a map could be faster with certain sizes of sort
lists. my module could support both kinds of output conversions. more on
that when i get a tuit.

uri
 
A

Anno Siegel

[Uri about resuming work on Sort::GRT]
record. but the flash was to just have the user supply the perl code for
that (assuming the record is in $_). this removes much of the complexity
of the module...

Way to go... Open the interface barn-door wide and let the user deal
with it. :)
AS> Another variant is to use an array slice to put the final sorted list
AS> together: "@raw[ map substr( $_, ...), sort ... ]". It's less readable,
AS> imo, so to be acceptable it would have to be faster, which I doubt.

that is a good point. a map could be faster with certain sizes of sort
lists. my module could support both kinds of output conversions. more on
that when i get a tuit.

Looking forward to it.

Anno
 
U

Uri Guttman

AS> [Uri about resuming work on Sort::GRT]

AS> Way to go... Open the interface barn-door wide and let the user deal
AS> with it. :)

and it removes over half the work from my shoulders. and it is the more
complex half at that!

AS> Looking forward to it.

send some tuits. or $$$. or free labor. :)

uri
 
A

Anno Siegel

[variants of GRT]
AS> Another variant is to use an array slice to put the final sorted list
AS> together: "@raw[ map substr( $_, ...), sort ... ]". It's less readable,
AS> imo, so to be acceptable it would have to be faster, which I doubt.

that is a good point. a map could be faster with certain sizes of sort
lists. my module could support both kinds of output conversions. more on
that when i get a tuit.

Out of curiosity I benchmarked. Other things equal, the slice came out
about 8% slower, for large and small sorts.

Anno
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top