Custom sort empties instead of sorting

W

Wes Groleau

I put a bunch of records in a hash. I need to output a subset
of the records, so I make a list of the keys needed. Output order
is not important EXCEPT that a certain key must always be first,
and a certain key last.

# here $Keys[0], $Keys[1], $Keys[5] all contain text

@Keys = sort
{
if ($a eq "HEAD") {return -1};
if ($b eq "HEAD") {return 1};
if ($a eq "TRLR") {return 1};
if ($b eq "TRLR") {return -1};
return 0;
} @Keys;

# here $Keys[0], $Keys[1], $Keys[5] are all undefined

Several variations on the style of the comparison black
all gave the same result. Assigning the sort to a different
array left the result array empty also.

What am I missing?

RTFM references OK,
as long as they're not 'perlfunc' or "Perl Cookbook" :)
 
A

A. Sinan Unur

What am I missing?

RTFM references OK,
as long as they're not 'perlfunc' or "Perl Cookbook" :)

No, the posting guidelines would be more appropriate in this case.

Please post the shortest possible script, along with data, that still
exhibits the problem so we can replicate and analyze the issue. In other
words, help others help you.

Oh, and do read the posting guidelines.

Sinan.
 
A

Anno Siegel

Wes Groleau said:
I put a bunch of records in a hash. I need to output a subset
of the records, so I make a list of the keys needed. Output order
is not important EXCEPT that a certain key must always be first,
and a certain key last.

# here $Keys[0], $Keys[1], $Keys[5] all contain text

@Keys = sort
{
if ($a eq "HEAD") {return -1};
if ($b eq "HEAD") {return 1};
if ($a eq "TRLR") {return 1};
if ($b eq "TRLR") {return -1};
return 0;
} @Keys;

# here $Keys[0], $Keys[1], $Keys[5] are all undefined

Several variations on the style of the comparison black
all gave the same result. Assigning the sort to a different
array left the result array empty also.

Gee, you're sorting an array, so the elements get shuffled about,
including undef's. The result is consistent with the data you're
giving, as far as I can see.
What am I missing?

I don't know, your code works as expected for me, but it's inefficient.
I suppose, "HEAD" and "TRLR" each appear only once. Then (untested)

@Keys = ( 'HEAD', grep( $_ ne 'HEAD', grep $_ ne 'TRLR', @Keys), 'TRLR');

does what you want more directly, and in linear time.

Anno
 
W

Wes Groleau

Anno said:
Gee, you're sorting an array, so the elements get shuffled about,
including undef's. The result is consistent with the data you're
giving, as far as I can see.

No,

1. I said the array after sorting is EMPTY.
Before sorting it had text in at least elements
[0], [1], and [5] Since it did have one HEAD,
I expected that to sort to [0]

2. Since the array is the keys of a hash, there
can be at most _one_ undef, not three.
I don't know, your code works as expected for me, but it's inefficient.

Hmm. Maybe a bug in my installation.
I suppose, "HEAD" and "TRLR" each appear only once. Then (untested)

@Keys = ( 'HEAD', grep( $_ ne 'HEAD', grep $_ ne 'TRLR', @Keys), 'TRLR');

does what you want more directly, and in linear time.

Thanks. That looks like it's worth a try. This is actually
better, because if the user forgets to put in the HEAD and TRLR,
they still get a valid output.

--
Wes Groleau

I've noticed lately that the paranoid fear of computers becoming
intelligent and taking over the world has almost entirely disappeared
from the common culture. Near as I can tell, this coincides with
the release of MS-DOS.
-- Larry DeLuca
 
W

Wes Groleau

And indeed, it worked. Still don't understand why the
other didn't, but ....

Thanks!

(By the way, what I _almost_ did was even more inefficient:
Save the HEAD and TRLR from the hash, delete them, print
the head, then all the values, then the trailer, then
reinsert the saved items.)
 
W

Wes Groleau

Abigail said:
Yeah, we won't help you, unless you're a golfer! ;-)

Neither golfer, nor flogger, nor blogger.

Just an invader from Ada-land [1] trying to use
the right tool [2] for the job.

[1] Does the following sound familiar?
"It's Ada, not ADA. How can you program in it
if you can't even spell it?"

[2] For this job, that would be a language with
built-in hashes and sophisticated pattern-matching.
 
A

A. Sinan Unur

Abigail said:
Yeah, we won't help you, unless you're a golfer! ;-)

Neither golfer, nor flogger, nor blogger.

Just an invader from Ada-land [1] trying to use
the right tool [2] for the job.

None of which is relevant. It is important that when you post here, you
post code that others can run. That's all.

Sinan
 
A

Anno Siegel

Wes Groleau said:
No,

1. I said the array after sorting is EMPTY.

Okay, it shouldn't be empty, but you only mentioned "empty" in the
subject.
Before sorting it had text in at least elements
[0], [1], and [5] Since it did have one HEAD,
I expected that to sort to [0]

You didn't mention specific content, only that some elements contain
"text". Yes, "HEAD" should end up in 0. It did for me when present.
2. Since the array is the keys of a hash, there
can be at most _one_ undef, not three.

No. A hash key can *never* be undefined, it is always a string. Also,
you didn't say that 5 was supposed to be the last element in the array.
There could have been any number of undef's beyond that.

With an older Perl, before sort was stable, nothing could be said about
elements 0, 1 and 5 after the sort.

It would have been better if you had specified the array completely.

Anno
 
A

Anno Siegel

Wes Groleau said:
And indeed, it worked. Still don't understand why the
other didn't, but ....

Thanks!

(By the way, what I _almost_ did was even more inefficient:
Save the HEAD and TRLR from the hash, delete them, print
the head, then all the values, then the trailer, then
reinsert the saved items.)

That's not so bad. It would also perform in linear time.

Anno
 
W

Wes Groleau

Anno said:
Okay, it shouldn't be empty, but you only mentioned "empty" in the
subject.

Sorry. But I did say it came from a hash.
No. A hash key can *never* be undefined, it is always a string. Also,

Hmm. I didn't know that. I thought there was a slim chance
that some error during creation of the hash might have used
an undef for a key.
you didn't say that 5 was supposed to be the last element in the array.
There could have been any number of undef's beyond that.

No, not the last, just one of the three cells I tested.
I believe there were over two thousand entries at the
time I tested. I can see that a sort (especially when
order is important for only two items) would be most
inefficient. But whatever my attempted sort did was
so fast that there was no noticeable delay between
invocation and error message.

Since my code worked for you, I wonder whether there
is a peculiar bug in my installation.

I may do some testing for that if I ever can afford them
time. But the grep solution works fine anyway.
 
T

Tad McClellan

Wes Groleau said:
Anno Siegel wrote:

Hmm. I didn't know that. I thought there was a slim chance
that some error during creation of the hash might have used
an undef for a key.


In which case the undef would be stringified, and you would
end up with an empty string as the key.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top