0

I am using this sort to arrange data in $arr how I need it.

It works very well, however, seems that it's losing the last array when there are more than 16.

I think the problem is with the data, but I've not found the source of the issue.

I when I use this array:

array ( 
0 => array ( 'race_order' => 1, 'heat_nbr' => 4, 'racer_id' => 620, 'heat_finish' => 4, 'race_time' => '120.00', ), 
1 => array ( 'race_order' => 1, 'heat_nbr' => 4, 'racer_id' => 645, 'heat_finish' => 5, 'race_time' => '120.00', ), 
2 => array ( 'race_order' => 1, 'heat_nbr' => 4, 'racer_id'=> 487, 'heat_finish' => 6, 'race_time' => '120.00', ), 
3 => array ( 'race_order' => 2, 'heat_nbr' => 3, 'racer_id' => 857, 'heat_finish' => 4, 'race_time' => '160.00', ), 
4 => array ( 'race_order' => 2, 'heat_nbr' => 3, 'racer_id'=> 1191, 'heat_finish' => 5, 'race_time' => '160.00', ), 
5 => array ( 'race_order' => 2, 'heat_nbr' => 3, 'racer_id' => 1269, 'heat_finish' => 6, 'race_time' =>'160.00', ), 
6 => array ( 'race_order' => 2, 'heat_nbr' => 3, 'racer_id'=> 723, 'heat_finish' => 7, 'race_time' => '160.00', ), 
7 => array ( 'race_order' => 3, 'heat_nbr' => 2, 'racer_id' => 245, 'heat_finish' => 3, 'race_time' =>'180.0000', ), 
8 => array ( 'race_order' => 3, 'heat_nbr' => 2, 'racer_id'=> 65, 'heat_finish' => 4, 'race_time' => '180.0000', ), 
9 => array ( 'race_order' => 3, 'heat_nbr' => 2, 'racer_id' => 269, 'heat_finish' => 5, 'race_time' =>'180.0000', ), 
10 => array ( 'race_order' => 3, 'heat_nbr' => 2,'racer_id' => 860, 'heat_finish' => 6, 'race_time' => '180.0000', ), 
11 => array ('race_order' => 3, 'heat_nbr' => 2, 'racer_id' => 226, 'heat_finish' => 7,'race_time' => '180.0000', ), 
12 => array ( 'race_order' => 4, 'heat_nbr'=> 1, 'racer_id' => 24, 'heat_finish' => 3, 'race_time' => '240.00', ),
13 => array ('race_order' => 4, 'heat_nbr' => 1, 'racer_id' => 1006, 'heat_finish' =>4, 'race_time' => '240.00', ), 
14 => array ( 'race_order' => 4, 'heat_nbr'=> 1, 'racer_id' => 625, 'heat_finish' => 5, 'race_time' => '240.00', ), 
15 => array ('race_order' => 4, 'heat_nbr' => 1, 'racer_id' => 1115, 'heat_finish' =>6, 'race_time' => '240.00', ), 
16 => array ( 'race_order' => 4, 'heat_nbr'=> 1, 'racer_id' => 1208, 'heat_finish' => 7, 'race_time' => '240.00', ), 
);

It works as expected. With the array included in the code below, I lose :

16 => array ( 'race_order' => 4, 'heat_nbr'=> 1, 'racer_id' => 1208, 'heat_finish' => 7, 'race_time' => '240.00', ), 

I can't see a good reason.

//the insertion sort    
function sortArr(&$arr){    

    for($i = 0; $i<count($arr); $i++){      //loop that iterates through the array indexes    
    //set the current index as the current minimum    
        $index = $i;    
        $posOfMin = $arr[$i];    

        for($k = $i+1; $k < count($arr); $k++){     //loop that iterates from the current index to the array end to find the smallest heat_finish value    
            if($arr[$k]['heat_finish'] < $arr[$index]['heat_finish']){      //if a value smaller than the current assumed minimum is found, that value will be set as the current minimum    
                $index = $k;    
                $posOfMin = $arr[$k];    
            }    
        }    
    //swaps the position of the current index and the current minimum    
        $arr[$index] = $arr[$i];    
        $arr[$i] = $posOfMin;    
}    
}    

$arr = array (    
0 => array ( 'nbr_of_semis' => 2, 'race_order' => 1, 'heat_nbr' => 3, 'racer_id' => 1191, 'heat_finish' => 4, 'race_time' => '121.0000', ),    
1 => array ( 'nbr_of_semis' => 2, 'race_order' => 1, 'heat_nbr' => 3, 'racer_id' => 502, 'heat_finish' => 5, 'race_time' => '121.0000', ),    
2 => array ( 'nbr_of_semis' => 2, 'race_order' => 1, 'heat_nbr' => 3, 'racer_id' => 1269, 'heat_finish' => 6, 'race_time' => '121.0000', ),    
3 => array ( 'nbr_of_semis' => 2, 'race_order' => 1, 'heat_nbr' => 3, 'racer_id' => 723, 'heat_finish' => 7, 'race_time' => '121.0000', ),    
4 => array ( 'nbr_of_semis' => 2, 'race_order' => 2, 'heat_nbr' => 1, 'racer_id' => 24, 'heat_finish' => 4, 'race_time' => '130.0000', ),    
5 => array ( 'nbr_of_semis' => 2, 'race_order' => 2, 'heat_nbr' => 1, 'racer_id' => 1006, 'heat_finish' => 5, 'race_time' => '130.0000', ),    
6 => array ( 'nbr_of_semis' => 2, 'race_order' => 2, 'heat_nbr' => 1, 'racer_id' => 625, 'heat_finish' => 6, 'race_time' => '130.0000', ),    
7 => array ( 'nbr_of_semis' => 2, 'race_order' => 2, 'heat_nbr' => 1, 'racer_id' => 1115, 'heat_finish' => 7, 'race_time' => '130.0000', ),    
8 => array ( 'nbr_of_semis' => 2, 'race_order' => 3, 'heat_nbr' => 4, 'racer_id' => 121, 'heat_finish' => 3, 'race_time' => '136.0000', ),    
9 => array ( 'nbr_of_semis' => 2, 'race_order' => 3, 'heat_nbr' => 4, 'racer_id' => 620, 'heat_finish' => 4, 'race_time' => '136.0000', ),    
10 => array ( 'nbr_of_semis' => 2, 'race_order' => 3, 'heat_nbr' => 4, 'racer_id' => 487, 'heat_finish' => 5, 'race_time' => '136.0000', ),    
11 => array ( 'nbr_of_semis' => 2, 'race_order' => 3, 'heat_nbr' => 4, 'racer_id' => 645, 'heat_finish' => 6, 'race_time' => '136.0000', ),    
12 => array ( 'nbr_of_semis' => 2, 'race_order' => 4, 'heat_nbr' => 2, 'racer_id' => 379, 'heat_finish' => 3, 'race_time' => '152.0000', ),    
13 => array ( 'nbr_of_semis' => 2, 'race_order' => 4, 'heat_nbr' => 2, 'racer_id' => 17, 'heat_finish' => 4, 'race_time' => '152.0000', ),    
14 => array ( 'nbr_of_semis' => 2, 'race_order' => 4, 'heat_nbr' => 2, 'racer_id' => 65, 'heat_finish' => 5, 'race_time' => '152.0000', ),    
15 => array ( 'nbr_of_semis' => 2, 'race_order' => 4, 'heat_nbr' => 2, 'racer_id' => 860, 'heat_finish' => 6, 'race_time' => '152.0000', ),    
16 => array ( 'nbr_of_semis' => 2, 'race_order' => 4, 'heat_nbr' => 2, 'racer_id' => 226, 'heat_finish' => 7, 'race_time' => '152.0000', )    
);    

$n = count($arr);    
//loop that prints the array    
for($i = 0; $i < $n; $i++)    
    echo nl2br("Sort Order:". $i ." Race Order:" . $arr[$i]['race_order'] . "| Heat Number:" . $arr[$i]['heat_nbr'] . "| Racer:" . $arr[$i]['racer_id'] . "| Heat Finish:" . $arr[$i]['heat_finish'] . "| Race Time:" . $arr[$i]['race_time']."\n");    

//loop that separates and sorts the racers according to their race_order    
$max = 0;           //variable that will use to determine the maximum size of race_order    
for($i = 0; $i < $n; $i++){    
    if($i == 0)    
        $arr1[] = $arr[$i];    
    else{    
        if($arr[$i]['race_order'] == $arr[$i-1]['race_order'])    
            $arr1[] = $arr[$i];    
        else{    
            sortArr($arr1);    
            $arr2[] = $arr1;    
            if($max < count($arr1))    
                $max  = count($arr1);    
            unset($arr1);    
            $arr1[] = $arr[$i];    
        }    
    }    
}    
$arr2[] = $arr1;    

//destroy the current array    
unset($arr);    


//loop to combine the sorted arrays    
for($i = 0; $i < $max; $i++){    
    for($j = 0; $j < count($arr2); $j++){    
        if(count($arr2[$j]) > $i)    
            $arr[] = $arr2[$j][$i];    
    }    
}    

echo nl2br("Sorted\n");    
for($i = 0; $i < $n; $i++)    
    echo nl2br("Sort Order:". $i ." Race Order:" . $arr[$i]['race_order'] . "| Heat Number:" . $arr[$i]['heat_nbr'] . "| Racer:" . $arr[$i]['racer_id'] . "| Heat Finish:" . $arr[$i]['heat_finish'] . "| Race Time:" . $arr[$i]['race_time']."\n");    
7
  • I have answered something similar : stackoverflow.com/questions/34771366/… Commented Jan 13, 2016 at 16:48
  • Why are you building your own sort function? Why not usort() with a simple comparator function? You're probably losing the entry because of a bug in your code causing it to get overwritten when you do your $arr[$index] and $arr[$i] assignments. Commented Jan 13, 2016 at 16:48
  • Tried that. Didn't work. I don't see why it will work perfectly on on set of data and not on another thats very similar. Commented Jan 13, 2016 at 16:50
  • @Alex I appreciate it, but that's not what I need here.. I need this sorted on multiple fields.. And not in a natural sort order. Commented Jan 13, 2016 at 16:56
  • Why are you calling count() 54 times on the same array? Also, is your bug here: "for($k = $i+1;" ?? Commented Jan 13, 2016 at 17:05

1 Answer 1

3

It's going wrong here:

// less than $max
for($i = 0; $i < $max; $i++){

The $max is a value based on the count() of $arr1, You should do

// less than OR equal to $max
for($i = 0; $i <= $max; $i++){

Else it will never parse the last value, as what happend here. :)

Sign up to request clarification or add additional context in comments.

1 Comment

Took me a while to look at this.. I've been sick all week and couldn't focus on the screen long enough to do anything. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.