Sorting Numberic keys in a hash array - with varying number lengths.

A

anthony

I had some code that would sort my keys in ascending order - no
problem.
Now what I have found is that when I introduce new values which are 6
digits (rather than 5 digits), it will place these are the beginning of
the list because they begin with the number 1.
My code is:
foreach $PackageToDeploy (sort(keys(%AparsToApply)))
{
print
"\t${PackageToDeploy}\t-\>\t$AparsToApply{$PackageToDeploy}\n";
}
which will produce the following:

57414 -> server1
57441 -> server1
57451 -> server1
57483 -> server1
57497 -> server1
57508 -> server1
57509 -> server1

Now when a new value is added to the array - lets say 101800. It will
put this at the top of the list rather than the bottom. It sorts on the
first digit first, but how can I get it to sort on the weight of the
number?
So what I want my output to be is:
57414 -> server1
57441 -> server1
57451 -> server1
57483 -> server1
57497 -> server1
57508 -> server1
57509 -> server1
101800 -> server1

I have had a look at the '$hash{$a} cmp $hash{b}' logic but it doesn't
seem to sort it the way I want, in fact it doesn't sort it at all.
 
C

Chris

anthony said:
I had some code that would sort my keys in ascending order - no
problem.
Now what I have found is that when I introduce new values which are 6
digits (rather than 5 digits), it will place these are the beginning of
the list because they begin with the number 1.
My code is:
foreach $PackageToDeploy (sort(keys(%AparsToApply)))
{
print
"\t${PackageToDeploy}\t-\>\t$AparsToApply{$PackageToDeploy}\n";
}
which will produce the following:

57414 -> server1
57441 -> server1
57451 -> server1
57483 -> server1
57497 -> server1
57508 -> server1
57509 -> server1

Now when a new value is added to the array - lets say 101800. It will
put this at the top of the list rather than the bottom. It sorts on the
first digit first, but how can I get it to sort on the weight of the
number?
So what I want my output to be is:
57414 -> server1
57441 -> server1
57451 -> server1
57483 -> server1
57497 -> server1
57508 -> server1
57509 -> server1
101800 -> server1

I have had a look at the '$hash{$a} cmp $hash{b}' logic but it doesn't
seem to sort it the way I want, in fact it doesn't sort it at all.
This sorts by value where you want to sort by key. This
should do the trick:

foreach $PackageToDeploy (sort {$a <=> $b} keys
(%AparsToApply)) {
...
}

HTH
Chris.
 
A

Anno Siegel

anthony said:
I had some code that would sort my keys in ascending order - no
problem.
Now what I have found is that when I introduce new values which are 6
digits (rather than 5 digits), it will place these are the beginning of
the list because they begin with the number 1.
My code is:
foreach $PackageToDeploy (sort(keys(%AparsToApply)))
{
print
"\t${PackageToDeploy}\t-\>\t$AparsToApply{$PackageToDeploy}\n";
}
which will produce the following:

57414 -> server1
57441 -> server1
57451 -> server1
57483 -> server1
57497 -> server1
57508 -> server1
57509 -> server1

Now when a new value is added to the array - lets say 101800. It will
put this at the top of the list rather than the bottom. It sorts on the
first digit first, but how can I get it to sort on the weight of the
number?

You're using the default sort which sorts alphabetically. See perldoc
-f sort for alternatives.
So what I want my output to be is:
57414 -> server1
57441 -> server1
57451 -> server1
57483 -> server1
57497 -> server1
57508 -> server1
57509 -> server1
101800 -> server1

I have had a look at the '$hash{$a} cmp $hash{b}' logic but it doesn't
seem to sort it the way I want, in fact it doesn't sort it at all.

That would sort by the values which are all "server1". What made
you think that might help?

The sort documentation has examples for numeric sorting. Apply them.

Anno
 
M

MikeGee

anthony said:
I had some code that would sort my keys in ascending order - no
problem.
Now what I have found is that when I introduce new values which are 6
digits (rather than 5 digits), it will place these are the beginning of
the list because they begin with the number 1.
My code is:
foreach $PackageToDeploy (sort(keys(%AparsToApply)))

Just change this to:
foreach $PackageToDeploy (sort {$a <=> $b} (keys(%AparsToApply)))

sort uses {$a cmp $b} by default; which sorts ASCIIbetically.
 
J

Jürgen Exner

anthony said:
I had some code that would sort my keys in ascending order - no
problem.
Now what I have found is that when I introduce new values which are 6
digits (rather than 5 digits), it will place these are the beginning
of the list because they begin with the number 1.
My code is:
foreach $PackageToDeploy (sort(keys(%AparsToApply))) [...]
Now when a new value is added to the array - lets say 101800. It will
put this at the top of the list rather than the bottom. It sorts on
the first digit first,

Unless told otherwise
but how can I get it to sort on the weight of the number?

Well, unless told otherwise sort() will sort in lexicographical order.
I have had a look at the '$hash{$a} cmp $hash{b}' logic

Right idea, wrong operator. Now you are asking explicitely(!) for a
lexicographical sort.
If you want to sort numerically then use the numerical comparison operator
<=> instead.

jue
 
J

Jürgen Exner

MikeGee said:
sort uses {$a cmp $b} by default; which sorts ASCIIbetically.

sort() is better than that. It even sorts alphabetically, not only just
ASCIIbetically.

jue
 

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