# Sorting arrays

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
I'm having some trouble understanding what is happening with some array
sorting functions. In all cases, my compare function is:
function compare(\$x, \$y)
{
if ( \$x[1] == \$y[1] )
return 0;
else if ( \$x[1] < \$y[1] )
return -1;
else
return 1;
}
I started with this:
\$contents = array( array( 'TIR', 'Tires', 100 ),
array( 'OIL', 'Oil', 10 ),
array( 'SPK', 'Spark Plugs', 4 ) );
echo '<br>XXX<br>';
foreach(\$contents as \$r) {
var_export(\$r);
echo '<br>';
}
echo '<br>YYY<br>';
uasort(\$contents, 'compare');
foreach(\$contents as \$r) {
var_export(\$r);
echo '<br>';
}
And the output, whether I use usort or uasort is always:
XXX
array ( 0 => 'TIR', 1 => 'Tires', 2 => 100, )
array ( 0 => 'OIL', 1 => 'Oil', 2 => 10, )
array ( 0 => 'SPK', 1 => 'Spark Plugs', 2 => 4, )

YYY
array ( 0 => 'OIL', 1 => 'Oil', 2 => 10, )
array ( 0 => 'SPK', 1 => 'Spark Plugs', 2 => 4, )
array ( 0 => 'TIR', 1 => 'Tires', 2 => 100, )
But if I use uksort I get:
XXX
array ( 0 => 'TIR', 1 => 'Tires', 2 => 100, )
array ( 0 => 'OIL', 1 => 'Oil', 2 => 10, )
array ( 0 => 'SPK', 1 => 'Spark Plugs', 2 => 4, )

YYY
array ( 0 => 'SPK', 1 => 'Spark Plugs', 2 => 4, )
array ( 0 => 'OIL', 1 => 'Oil', 2 => 10, )
array ( 0 => 'TIR', 1 => 'Tires', 2 => 100, )

But I cannot see why I get this reversal of order???

I then tried:
\$contents = array( array( c=>'TIR', d=>'Tires', p=>100 ),
array( c=>'OIL', d=>'Oil', p=>10 ),
array( c=>'SPK', d=>'Spark Plugs', p=>4 ) );

echo '<br>XXX<br>';
foreach(\$contents as \$r) {
var_export(\$r);
echo '<br>';
}
echo '<br>YYY<br>';
uksort(\$contents, 'compare');
foreach(\$contents as \$r) {
var_export(\$r);
echo '<br>';
}

And this time the output, whether I use usort, uasort or uksort is always:
XXX
array ( 'c' => 'TIR', 'd' => 'Tires', 'p' => 100, )
array ( 'c' => 'OIL', 'd' => 'Oil', 'p' => 10, )
array ( 'c' => 'SPK', 'd' => 'Spark Plugs', 'p' => 4, )

YYY
array ( 'c' => 'SPK', 'd' => 'Spark Plugs', 'p' => 4, )
array ( 'c' => 'OIL', 'd' => 'Oil', 'p' => 10, )
array ( 'c' => 'TIR', 'd' => 'Tires', 'p' => 100, )

Finally I tried:
\$contents = array( array( c=>'TIR', d=>'Tires', p=>100 ),
array( c=>'OIL', a=>'Oil', p=>10 ),
array( c=>'SPK', z=>'Spark Plugs', p=>4 ) );

echo '<br>XXX<br>';
foreach(\$contents as \$r) {
var_export(\$r);
echo '<br>';
}
echo '<br>YYY<br>';
uksort(\$contents, 'compare');
foreach(\$contents as \$r) {
var_export(\$r);
echo '<br>';
}
And once again, the outputs with usort, uasort or uksort is always:
XXX
array ( 'c' => 'TIR', 'd' => 'Tires', 'p' => 100, )
array ( 'c' => 'OIL', 'd' => 'Oil', 'p' => 10, )
array ( 'c' => 'SPK', 'd' => 'Spark Plugs', 'p' => 4, )

YYY
array ( 'c' => 'SPK', 'd' => 'Spark Plugs', 'p' => 4, )
array ( 'c' => 'OIL', 'd' => 'Oil', 'p' => 10, )
array ( 'c' => 'TIR', 'd' => 'Tires', 'p' => 100, )

Can someone explain why none of the cases will sort the associative array by
the second "column" and how I can find examples that will sow the
differences between the 3 sort functions???

TIA
Paul

## Re: Sorting arrays

I understand a bit more about it now, having tried something else, but I
still can't find a difference between usort and uasort and neither can I
figure out how to use uksort?

## Re: Sorting arrays

Paul Lautman wrote:

What is going wrong in the code from your previous post is that you are
using numeric indexes on associative arrays, contained in \$x and \$y, which

Compare the following implementation with the one from your previous post:

function compare(\$a, \$b) {
list(,\$var_a) = array_values(\$a);
list(,\$var_b) = array_values(\$b);
if (\$var_a == \$var_b) return 0;
return \$var_a < \$var_b ? -1 : 1;
}

As you will see, list extracts the value from the second index from the
array returned by array_values when applied to \$a and \$b.

The difference between usort and uasort, is that the latter preserves the
index association, while the first doesn't. As an example, with usort, the
result will always be:

array( 0 => ..., 1 => ....);

while with uasort, depending on the structure of the original array, the
result can be:

array( 1 => ..., 0 => ....);

The uksort function uses the keys/indexes, while the uasort function uses
the values for sorting. For the array structure you've posted, uksort
appears to be useless.

JW

## Re: Sorting arrays

Janwillem Borleffs wrote:

Yeah I worked out the indexes problem.

Can you give me an example of where usort and uasort give different outputs
and how uksort would be used?

## Re: Sorting arrays

Paul Lautman wrote:

function cmp(\$a, \$b) {
if (\$a == \$b) return 0;
return \$a < \$b ? -1 : 1;
}

\$array = array('b' => 200, 'a' => 50, 'A' => 100);
\$usort = \$uasort = \$uksort = \$array;

print 'original array:<br>';
print_r(\$array);

print '<hr>usort: sorted by value, keys are not preserved:<br>';
usort(\$usort, 'cmp');
print_r(\$usort);

print '<hr>uasort: sorted by value, keys are preserved:<br>';
uasort(\$uasort, 'cmp');
print_r(\$uasort);

print '<hr>uksort: sorted by key;<br>';
print '"A" put before "a" because of its lower ASCII value:<br>';
uksort(\$uksort, 'cmp');
print_r(\$uksort);

JW

## Re: Sorting arrays

Janwillem Borleffs wrote:

Cheers for that, do you also know why I see the oder reversal (see the first
post)?

## Re: Sorting arrays

Paul Lautman wrote:

In your original compare function, the passed numeric indexes are converted
to strings (because of the var[1] syntax, which is a deprecated use of
var with scalars) of which you are requesting the second character that
doesn't exist. In effect, you are comparing '' with '', which is equal.

If you look at the sequences passed, from the original array, index 1 is
compared to index 0 and index 2 is compared to index 1.

The result of the first comparison would be:

1 => array( 'OIL', 'Oil', 10 )
0 => array( 'TIR', 'Tires', 100 )

The result of the second comparison would be:

2 => array( 'SPK', 'Spark Plugs', 4 )
1 => array( 'OIL', 'Oil', 10 )
0 => array( 'TIR', 'Tires', 100 )

So, the reversal effect is the result of the first argument passed to the
compare function being considered to be equal to the second one and they are
therefore sorted in the order they where passed.

JW

## Re: Sorting arrays

Janwillem Borleffs wrote:

"which is a deprecated use of var with scalars" should read:
"which is a deprecated use of var on strings"

JW

## Re: Sorting arrays

Janwillem Borleffs wrote:

Thank you for your very full and thorough explanation.

## Re: Sorting arrays

On Sat, 20 May 2006 23:46:54 +0100, Paul Lautman wrote:

Try with this:

function compare(\$x, \$y)
{
GLOBAL \$contents;
if (\$contents[\$x] == \$contents[\$y])
return(0);
else
return (\$contents[\$x]<\$contents[\$y]? -1:1);

}

--
http://www.mgogala.com

## Re: Sorting arrays

What is this supposed to achieve?

## Re: Sorting arrays

On Sun, 21 May 2006 13:02:53 +0100, Paul Lautman wrote:

Sort hash keys according to the hash values.

--
http://www.mgogala.com