Forum Moderators: coopster

Message Too Old, No Replies

how does usort work?

         

jiggy1965

9:04 pm on Mar 19, 2010 (gmt 0)

10+ Year Member



I'm trying to understand how usort works. So I used this code:
<?php
function usort_cmp($a, $b) {
echo $a . "->" . $b . "<br />\n";

}

$arr = array(1,2,3,4);
usort($arr, "usort_cmp");

?>


Which results in the following output:
2->1
4->2
3->2
4->3

But I can't understand why this output is like it is?
I've read that usort uses the bubblesort methode. Looked on wikipedia how that worked. So I expected it to loop through the array as follows:

compare 1 with 2 (switch if necessary)
compare 2 with 3 (switch if necessary)
compare 3 with 4 (switch if necessary)
compare 1 with 2 (switch if necessary)
compare 2 with 3 (switch if necessary)
compare 1 with 2 (switch if necessary)

Can someone explain to me why usort outputs this random looking comparison (though not really random cause it is the same every time I run the script).

Matthew1980

10:48 pm on Mar 19, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



hi there jiggy1965,

see if this helps:-

[uk.php.net ]

Unless that's where you got it from ;-p

Cheers,
MRb

Anyango

9:15 am on Mar 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The above referenced page says


This function will sort an array by its values using a user-supplied comparison function


But your function is not comparing anything, its just an echo. According to my understanding, in that function you need to do a comparison of those two values and return something back to usort, in order for it to work.
Have a look at "Example #1 usort() example" on the page that Matthew1980 has refered.

jiggy1965

2:49 pm on Mar 20, 2010 (gmt 0)

10+ Year Member



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

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

foreach ($a as $key => $value) {
echo "$key: $value\n";
}
?>


That's indeed where I got this from. But I wanted to know what $a and $b was. So I just narrowed this script down to a simple echo. I understood that the function usort was calling probably was going through a loop. Comparing $a with $b until all values where compared and as a result everything was sorted. So I used a echo line to see each combination of comparison values. To see which value was compared to which other value during all loops.

In my script this led to 4 comparisons in the loop, resulting in these comparisons:
2->1
4->2
3->2
4->3

Normally these four comparisons would lead to the order of 1,2,3,4 (which is already was, but that's not important). But I was trying to understand why it first compares 2 with 1, then 4 with 2, then 3 with 2 and finally 4 with 3. Couldn't make sence of that.

Why, for example, doesn't it first compare 2 with 1, then 3 with 2, then 4 with 3? Or any other order that makes sense?

There must be some logic behind it, cause the result is the same each time I run the script.

Matthew1980

6:40 pm on Mar 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there jiggy1965,

I myself was unsure of this so I had a little play as its the first time I have used this function.

From what I can see the usort(); function compares the contents of the chosen array and returns the result in array format, so that you can loop through each instance, HIGHEST significance to LOWEST, ie: the most matched numbers (or equal too ==) first, then for the end of the loop, the least matched (or not equal !=) entries in the given array:-


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

$a = array(1, 3, 6, 3, 1);

usort($a, "cmp");

foreach ($a as $key => $value) {
echo "$key: $value<br>";
}


This version that I have done outputs:-

0: 1
1: 1
2: 3
3: 3
4: 6

As expected because (math wise) 1 is the most significant or lowest value next to 3, of which again there are two instances of, and then there is only a single 6.

The more ints that you add to the array you will see the effect. Also I wont matter where in the array you place the ints as the comparator in the function will always re-order most significant to least significant, at least that how I perceive it ;-p

I now understand the effects of usort(); and possible uses, hopefully that will shed a bit of light on the subject.

Cheers,

MRb

Anyango

6:16 am on Mar 22, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Jiggy imho i think you are still repeating same error that is why its leading you to confusion about how it works. If your compare function doesnt compare, and just echoes something, you wil always get that same output without any comparisons being made or without any sorting being done. In your comparison function, if you want to see the values, please echo them But still return them after comparison for usort, Your echo will be for you but usort function also expects something from the comparison function so send something to that too :)


try this

function usort_cmp($a, $b)
{
echo $a . "->" . $b . "<br />\n";
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}