note 67936 deleted from function.usort by danbrown

From: Date: Sun, 23 Jan 2011 16:26:42 +0000
Subject: note 67936 deleted from function.usort by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-176067@lists.php.net to get a copy of this message
Note Submitter: g8z at yahoo dot com ---- <?php /** This sort function allows you to sort an associative array while "sticking" some fields. $sticky_fields = an array of fields that should not be re-sorted. This is a method of achieving sub-sorts within contiguous groups of records that have common data in some fields. For example: $a = array(); $a []= array( 'name' => 'Sam', 'age' => 23, 'hire_date' => '2004-01-01' ); $a []= array( 'name' => 'Sam', 'age' => 44, 'hire_date' => '2003-03-23' ); $a []= array( 'name' => 'Jenny', 'age' => 20, 'hire_date' => '2000-12-31' ); $a []= array( 'name' => 'Samantha', 'age' => 50, 'hire_date' => '2000-12-14' ); $sticky_fields = array( 'name' ); print_r( stickysort( $a, 'age', DESC_NUM, $sticky_fields ) ); OUTPUT: Array ( [0] => Array ( [name] => Sam [age] => 44 [hire_date] => 2003-03-23 ) [1] => Array ( [name] => Sam [age] => 23 [hire_date] => 2004-01-01 ) [2] => Array ( [name] => Jenny [age] => 20 [hire_date] => 2000-12-31 ) [3] => Array ( [name] => Samantha [age] => 50 [hire_date] => 2000-12-14 ) ) Here's why this is the correct output - the "name" field is sticky, so it cannot change its sort order. Thus, the "age" field is only sorted as a sub-sort within records where "name" is identical. Thus, the "Sam" records are reversed, because 44 > 23, but Samantha remains at the bottom, even though her age is 50. This is a way of achieving "sub-sorts" and "sub-sub-sorts" (and so on) within records of identical data for specific fields. Courtesy of the $5 Script Archive: http://www.tufat.com **/ define( 'ASC_AZ', 1000 ); define( 'DESC_AZ', 1001 ); define( 'ASC_NUM', 1002 ); define( 'DESC_NUM', 1003 ); function stickysort( $arr, $field, $sort_type, $sticky_fields = array() ) { $i = 0; foreach ($arr as $value) { $is_contiguous = true; if(!empty($grouped_arr)) { $last_value = end($grouped_arr[$i]); if(!($sticky_fields == array())) { foreach ($sticky_fields as $sticky_field) { if ($value[$sticky_field] <> $last_value[$sticky_field]) { $is_contiguous = false; break; } } } } if ($is_contiguous) $grouped_arr[$i][] = $value; else $grouped_arr[++$i][] = $value; } $code = ''; switch($sort_type) { case ASC_AZ: $code .= 'return strcasecmp($a["'.$field.'"], $b["'.$field.'"]);'; break; case DESC_AZ: $code .= 'return (-1*strcasecmp($a["'.$field.'"], $b["'.$field.'"]));'; break; case ASC_NUM: $code .= 'return ($a["'.$field.'"] - $b["'.$field.'"]);'; break; case DESC_NUM: $code .= 'return ($b["'.$field.'"] - $a["'.$field.'"]);'; break; } $compare = create_function('$a, $b', $code); foreach($grouped_arr as $grouped_arr_key=>$grouped_arr_value) usort ( $grouped_arr[$grouped_arr_key], $compare ); $arr = array(); foreach($grouped_arr as $grouped_arr_key=>$grouped_arr_value) foreach($grouped_arr[$grouped_arr_key] as $grouped_arr_arr_key=>$grouped_arr_arr_value) $arr[] = $grouped_arr[$grouped_arr_key][$grouped_arr_arr_key]; return $arr; } ?>

« previous php.notes (#176067) next »