note 35230 added to function.array-multisort

From: Date: Sun, 24 Aug 2003 12:33:19 +0000
Subject: note 35230 added to function.array-multisort
Groups: php.notes 
Request: Send a blank email to php-notes+get-54988@lists.php.net to get a copy of this message
More on sorting arrays of "rows", by their columns: Building on the ideas of "Ichier" and "steve at mg-rover dot org" below, I have combined this into a function which will sort a 2-dimensional array (ie an array of rows) by its columns. Unlike Ichiers function it will preserve the keys of the rows by using Steve's "_" trick. I first tried to achieve the column sort with a "transpose->array_multisort->transpose" approach, but then realiased that Ichier's code was better, because it saves the second transpose (thanks Ichier). The new fucntion (which I have named array_column_sort() to be more within the php convention) works well, but has the following disadvantage still. It requires making 2 copies of your original array: - one copy within the function to do the "_" prefixing which saves the keys. If anyone knows how to modify all the keys in an array of arrays without making a copy of it, let me know. This copy of the original array is temporary because it is local to the function. - Plus a second copy because the function (unlike array_multisort) doesn't operate on the array you pass it, but returns a new array. This is because Ichiers code uses func_get_args() to keep the syntax of the function flexible and func_get_args() doesn't handle, passing by reference. If anyone can think of a way around this also let me know. This should definitely be a standard php function, because this is a very common problem, since db results always come in this form. Here is the code for the new array_column_sort function: <?php /** * array_column_sort * * function to sort an "arrow of rows" by its columns * exracts the columns to be sorted and then * uses eval to flexibly apply the standard * array_multisort function * * uses a temporary copy of the array whith "_" prefixed to the keys * this makes sure that array_multisort is working with an associative * array with string type keys, which in turn ensures that the keys * will be preserved. * * TODO: find a way of modifying the keys of $array directly, without using * a copy of the array. * * flexible syntax: * $new_array = array_column_sort($array [, 'col1' [, SORT_FLAG [, SORT_FLAG]]]...); * * original code credited to Ichier (www.ichier.de) here: * http://uk.php.net/manual/en/function.array-multisort.php * * prefixing array indeces with "_" idea credit to steve at mg-rover dot org, also here: * http://uk.php.net/manual/en/function.array-multisort.php * */ function array_column_sort() { $args = func_get_args(); $array = array_shift($args); // make a temporary copy of array for which will fix the // keys to be strings, so that array_multisort() doesn't // destroy them $array_mod = array(); foreach ($array as $key => $value) $array_mod['_' . $key] = $value; $i = 0; $multi_sort_line = "return array_multisort( "; foreach ($args as $arg) { $i++; if ( is_string($arg) ) { foreach ($array_mod as $row_key => $row) { $sort_array[$i][] = $row[$arg]; } } else { $sort_array[$i] = $arg; } $multi_sort_line .= "\$sort_array[" . $i . "], "; } $multi_sort_line .= "\$array_mod );"; eval($multi_sort_line); // now copy $array_mod back into $array, stripping off the "_" // that we added earlier. $array = array(); foreach ($array_mod as $key => $value) $array[ substr($key, 1) ] = $value; return $array; } ?> Hope it helps, and maybe gets included in a future php version. Oliver ---- Manual Page -- http://www.php.net/manual/en/function.array-multisort.php Edit Note -- http://master.php.net/manage/user-notes.php?action=edit+35230 Delete Note -- http://master.php.net/manage/user-notes.php?action=delete+35230&report=yes Reject Note -- http://master.php.net/manage/user-notes.php?action=reject+35230&report=yes

« previous php.notes (#54988) next »