PHP 2-dimensional array sorting algorithms

For 2-dimensional arrays looking like:

[code]
Array
(
[0] => Array
(
[id] => 1
[name] => roger
[age] => 31
)

[1] => Array
(
[id] => 2
[name] => brutus
[age] => 24
)

[2] => Array
(
[id] => 3
[name] => ganesh
[age] => 92
)

)
[/code]

I find that comb sort is usually the fastest but its worst case is much worst than quick sort so it could become a bottleneck depending on your data.

[php]
<?php

ini_set( ‘memory_limit’, ‘128M’ ) ;

/**
* @desc bubble_sort for 2 dimensional array (all the arrays of the 2nd dimension need to have the field $sort_by)
* @param array^2 $data the array of arrays
* @param string $sort_by the parameter that will be used for comparison
* @param string $sort_direction "asc": ascending, "desc": descending
*/
function bubble_sort( $data, $sort_by, $sort_direction ) {
if( $sort_direction==’asc’ ) {
for( $i=1 ; $i<count($data) ; $i++ ) {
for( $j=1 ; $j<count($data) ; $j++ ) {
if( $data[$j-1][$sort_by]>$data[$j][$sort_by] ) {
$temp = $data[$j-1] ;
$data[$j-1] = $data[$j] ;
$data[$j] = $temp ;
}
}
}
} else {
for( $i=1 ; $i<count($data) ; $i++ ) {
for( $j=1 ; $j<count($data) ; $j++ ) {
if( $data[$j-1][$sort_by]<$data[$j][$sort_by] ) {
$temp = $data[$j-1] ;
$data[$j-1] = $data[$j] ;
$data[$j] = $temp ;
}
}
}
}
return $data ;
}

/**
* @desc comb_sort for 2 dimensional array (all the arrays of the 2nd dimension need to have the field $sort_by)
* @param array^2 $data the array of arrays
* @param string $sort_by the parameter that will be used for comparison
* @param string $sort_direction "asc": ascending, "desc": descending
*/
function comb_sort( $data, $sort_by, $sort_direction ) {
$gap = count( $data ) ;
$swaps = -1 ;
while( !($gap<=1 && $swaps==0) ) {
if( $gap>1 ) {
$gap = $gap/1.3 ;
if( $gap==10 || $gap==9 ) {
$gap = 11 ;
}
}
$i = 0 ;
$swaps = 0 ;
while( !(($i+$gap)>=count($data)) ) {
if( ($sort_direction==’asc’ && $data[$i][$sort_by]>$data[$i+$gap][$sort_by]) ||
($sort_direction==’desc’ && $data[$i][$sort_by]<$data[$i+$gap][$sort_by]) ) {
$temp = $data[$i] ;
$data[$i] = $data[$i+$gap] ;
$data[$i+$gap] = $temp ;
$swaps = 1 ;
}
$i++ ;
}
}

return $data ;
}

/**
* @desc quick_sort for 2 dimensional arrays (all the arrays of the 2nd dimension need to have the field $sort_by)
* @param array^2 $data the array of arrays
* @param string $sort_by the parameter that will be used for comparison
* @param string $sort_direction "asc": ascending, "desc": descending
*/
function quick_sort( $data, $sort_by, $sort_direction ) {
if( count($data)<=1 || $sort_by==” ) {
return $data ;
} else {
$pivot = $data[0][$sort_by] ;
$x = $y = array() ;
for( $i=1 ; $i<count($data) ; $i++ ) {
if( $data[$i][$sort_by]<$pivot ) {
if( $sort_direction=="asc" ) {
$x[] = $data[$i] ;
} else {
$y[] = $data[$i] ;
}
} else {
if( $sort_direction=="asc" ) {
$y[] = $data[$i] ;
} else {
$x[] = $data[$i] ;
}
}
}
return array_merge( quick_sort($x, $sort_by, $sort_direction), array($data[0]), quick_sort($y, $sort_by, $sort_direction) ) ;
}
}
?>
[/php]

Gnuplot one-liner from Hell

Here’s a convenient one liner to chronologically plot data on the command line

Screenshot

Screen Shot 2014-04-02 at 11.18.44 AM

Command

[bash]

export width=`stty size | cut -d " " -f2`; export height=`stty size | cut -d " " -f1`-10; cat /tmp/data | sed "s/ /T/" | gnuplot -e "set terminal dumb $width $height; set autoscale; set xdata time; set timefmt \"%Y-%m-%dT%H:%M:%S\"; set xlabel \"time\"; set ylabel \"counter\"; plot ‘-‘ using 1:2 with lines"

[/bash]

Data

/tmp/data contains the following:

[code]2000-01-01 00:00:00 1
2000-01-01 01:00:00 2
2000-01-01 02:00:00 3
2000-01-01 03:00:00 2
2000-01-01 04:00:00 3
2000-01-01 05:00:00 4
2000-01-01 06:00:00 5
2000-01-01 07:00:00 4
2000-01-01 08:00:00 3
2000-01-01 09:00:00 4
2000-01-01 10:00:00 4
2000-01-01 11:00:00 5
2000-01-01 12:00:00 4
2000-01-01 13:00:00 4
2000-01-01 14:00:00 3
2000-01-01 15:00:00 2
2000-01-01 16:00:00 3
2000-01-01 17:00:00 4
2000-01-01 18:00:00 4
2000-01-01 19:00:00 5
2000-01-01 20:00:00 6
2000-01-01 21:00:00 6
2000-01-01 22:00:00 7
2000-01-01 23:00:00 8
2000-01-02 00:00:00 7
2000-01-02 01:00:00 7
2000-01-02 02:00:00 6
2000-01-02 03:00:00 8
2000-01-02 04:00:00 9
2000-01-02 05:00:00 9
2000-01-02 06:00:00 9
2000-01-02 07:00:00 8
2000-01-02 08:00:00 7
2000-01-02 09:00:00 5
2000-01-02 10:00:00 4
2000-01-02 11:00:00 4
2000-01-02 12:00:00 4
2000-01-02 13:00:00 3
2000-01-02 14:00:00 2
2000-01-02 15:00:00 2
2000-01-02 16:00:00 1[/code]