Skip to content

Instantly share code, notes, and snippets.

@allthingscode
Created January 28, 2011 21:51
Show Gist options
  • Save allthingscode/801062 to your computer and use it in GitHub Desktop.
Save allthingscode/801062 to your computer and use it in GitHub Desktop.
/**
* @param unsortedRecords The array that needs to be sorted. This array must be in the typical
* format that our arrays are in after retrieving database data (i.e. array of records).
* @param sortKeys The record keys that we'll be sorting on.
* If this is an array, multi-column sorting will be done.
* @param sortDirections The direction to sort the columns.
* If this is an array, it should match up with the sort_keys array.
* @param sortTypes The type of sorting that should be done (SORT_NUMERIC, SORT_STRING, etc. )
* If this is an array, it should match up with the sort_keys array.
* @example To sort records by 'last_name' in descending order:
* $sortedArray = multisortRecords( $records, 'last_name', SORT_DESC )
* @example To sort records by 'last_name' ascending, then 'first_name' descending:
* $sortedArray = multisortRecords( $records, array( 'last_name', 'first_name' ), array( SORT_ASC, SORT_DESC ) )
* @author - Matthew Hayes <Matthew.Hayes@AllThingsCode.com
*/
function multisortRecords( &$unsortedRecords, $sortKeys, $sortDirections = SORT_ASC, $sortTypes = null )
{
if( ( ! is_array( $unsortedRecords ) ) || ( ! count( $unsortedRecords ) ) ) {
return array();
}
// Convert params to arrays if they are not already.
if( ! is_array( $sortKeys ) ) {
$_sort_keys = array( $sortKeys );
}
if( ! is_array( $sortDirections ) ) {
$sortDirections = array_fill( 0, count( $sortKeys ), $sortDirections );
}
if( ! is_array( $sortTypes ) ) {
$sortTypes = array_fill( 0, count( $sortKeys ), $sortTypes );
}
// Convert the sort directions in case they are plain text
foreach( array_keys( $sortDirections ) as $key ) {
switch( $sortDirections[ $key ] ) {
case SORT_ASC:
case SORT_DESC:
break;
case 'DESC':
case 'SORT_DESC':
$sortDirections[ $key ] = SORT_DESC;
break;
case 'ASC':
case 'SORT_ASC':
default:
$sortDirections[ $key ] = SORT_ASC;
}
}
// Convert the sort types in case they are plain text
foreach( array_keys( $sortTypes ) as $key ) {
switch( $sortTypes[ $key ] ) {
case SORT_NUMERIC:
case SORT_STRING:
break;
case 'NUMERIC':
case 'SORT_NUMERIC':
$sortTypes[ $key ] = SORT_NUMERIC;
break;
case 'STRING':
case 'SORT_STRING':
$sortTypes[ $key ] = SORT_STRING;
break;
default:
$sortTypes[ $key ] = null;
}
}
// Convert the data we'll be sorting on to column format
$sortColumns = array();
foreach( $unsortedRecords as $key => $record ) {
$sortColumns['primary_key'][ $key ] = $key;
foreach( $sortKeys as $sortKeyIndex => $sortKeyName ) {
$sortColumns[ $sortKeyName ][ $key ] = $record[ $sortKeyName ];
}
}
// Generate parameters for array_multisort()
$arrayMultisortParams = array();
for( $i = 0; $i < count( $sortKeys ); $i++ ) {
$arrayMultisortParams[] = $sortColumns[ $sortKeys[ $i ] ];
$arrayMultisortParams[] = $sortDirections[ $i ];
if( ! is_null( $sortTypes[ $i ] ) ) {
$arrayMultisortParams[] = $sortTypes[ $i ];
}
}
// We HAVE to pass in the primary_key column so that we can put it all back together later.
$arrayMultisortParams[] = $sortColumns['primary_key'];
// This is where the actual sort is done. See Also: http://us.php.net/manual/en/function.array-multisort.php
call_user_func_array( 'array_multisort', $arrayMultisortParams );
// Convert back to record format.
// We just build a new sorted array
// using the primary_key column (which is in the correct order now).
$sortedRows = array();
foreach( $sortColumns['primary_key'] as $key ) {
$sortedRows[ $key ] = $unsortedRecords[ $key ];
}
return $sortedRows;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment