PDA

View Full Version : Multidimensional array sorting problem



Krazifan
Aug 8th, 2002, 01:02 PM
Here is my problem. I’m trying to sort a multi-dimensional array by an array value in the second array. Here is an example of how I build the array structure (this is a simplified version of multiple selects that preclude me from just using an order by):

$result = sql_query(“select * from stats”, $dbi);
while($player = sql_fetch_array($result, $dbi)) {
  $allplayer[] = $player;
}

This gives me a multi-dimensional array that should resemble my database table, correct? Now, I want to sort on an array value in $player. I’ve tried to get multisort and a few others working to no avail and I just decided to write my own bubblesort.

function multi_bs ($array1,$sortkey) {
  global $done;
  $done = 1 ;
  while($done == 1) {
    $done = 0;
    for ($i = count($array1); $i > 0; $i--) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($array1[$i][$sortkey] < $array1[$i-1][$sortkey]) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$done = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$holder = $array[$i] ;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$array[$i] = $array[$i-1];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$array[$i-1] = $holder;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;return($array1);
}

The code above times out (infinite loop). Part of the problem is once the array gets into the bubblesort function, I can’t access the second array. It counts the number of values in array1 correctly (and passes it back to the calling function correctly), but I can’t access anything using $array1[#][#] or $array1[#][assoc.]. If I can fix that, I think it will solve my infinite loop.

Any ideas? Thanks.

Ökii
Aug 8th, 2002, 02:16 PM
I still don't understand why you cannot use order by in the select call
$result = sql_query(“select * from stats ORDER BY player ASC”, $dbi);
and then just sort($allplayer); at the end.

Another similar method would be to build an associative array with a declared array index based on a field of choice

eval("\$allplayer['".$player[2]."'] = ".$player.";");

fly typed - ergo I bet that parses dodgy.

Krazifan
Aug 8th, 2002, 02:25 PM
The reason I can't do an ORDER BY in my select statement is because I'm querying several tables and the resulting set (that needs to be sorted) is summed on several fields within the PHP program. I can't sum them in my query, because I need the individual values to compute a seperate value. It might be better to illustrate what I'm trying to do with pseudocode.

1. Read in player header record based on criteria.
2. For each player record, read multiple records from weekly_stats.
3. Each week, calculate the points based on the stats.
4. Sum the stats and points so that the grand totals can be put with the player information to form one record with the player's info and year to date stats.
5. Put this record into an array (thus forming a multi-dimensional array)
6. Repeat steps 2-5 for each player.
7. Resulting data needs to be sortable on all fields.

The main snag is calculating the points on a weekly basis. Calculating on the totals will yield a different result otherwise I would have done everything in one SQL query.

I only listed a very simplified snipet of code to illustrate what my array looks like :)

Krazifan
Aug 8th, 2002, 03:31 PM
HAH!! Wouldn't you know. I searched all night and couldn't find anything. As soon as I post it here, I find the answer. Here is the code I found to be able to do the sort I needed either ascending or descending.



function Compare_desc ($left, $right)
{
if ($left < $right)
return(-1);
elseif ($right < $left)
return(1);
}

function Compare_asc ($left, $right)
{
if ($left > $right)
return(-1);
elseif ($right > $left)
return(1);
}

function advanced_2Darray_sort($array, $index_name, $order)
{
$i = 0;
foreach ($array[0] as $key=>$data)
{
$sys_KEYLIST[$i] = $key;
$i++;
}

//assemble all the arrays...
for ($i = 0; $i < count($sys_KEYLIST); $i++)
{
${$sys_KEYLIST[$i]} = array();

for ($j = 0; $j < count($array); $j++)
${$sys_KEYLIST[$i]}[$j] = $array[$j][$sys_KEYLIST[$i]];
}

if ($order == "ASC") { uasort(${$index_name}, "Compare_asc");}
else { uasort(${$index_name}, "Compare_desc");}

$i = 0;
foreach (${$index_name} as $sort_key=>$junk)
{
for ($j = 0; $j < count($sys_KEYLIST); $j++)
$new_array[$i][$sys_KEYLIST[$j]] = ${$sys_KEYLIST[$j]}[$sort_key];

$i++;
}

return($new_array);
}


You would call this using :

new_array = advanced_2Darray_sort($old_array,$sortby,"ASC");

Anything other than ASC in the final argument will sort it descending.