©
このドキュメントでは、 php中国語ネットマニュアル リリース
(PHP 4, PHP 5, PHP 7)
array_multisort — 对多个数组或多维数组进行排序
&$arr
[, mixed $arg
= SORT_ASC
[, mixed $arg
= SORT_REGULAR
[, mixed $...
]]] )array_multisort() 可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序。
关联( string )键名保持不变,但数字键名会被重新索引。
排序顺序标志:
SORT_ASC
- 按照上升顺序排序 SORT_DESC
- 按照下降顺序排序 排序类型标志:
SORT_REGULAR
- 将项目按照通常方法比较 SORT_NUMERIC
- 将项目按照数值比较 SORT_STRING
- 将项目按照字符串比较
每个数组之后不能指定两个同类的排序标志。每个数组后指定的排序标志仅对该数组有效 - 在此之前为默认值
SORT_ASC
和 SORT_REGULAR
。
输入数组被当成一个表的列并以行来排序——这类似于 SQL 的 ORDER BY 子句的功能。第一个数组是要排序的主要数组。数组中的行(值)比较为相同的话就按照下一个输入数组中相应值的大小来排序,依此类推。
本函数的参数结构有些不同寻常,但是非常灵活。第一个参数必须是一个数组。接下来的每个参数可以是数组或者是下面列出的排序标志。
arr
要排序的一个 array 。
arg
接下来的每个参数可以是另一个 array 或者是为之前 array 排序标志选项参数:
SORT_ASC
,
SORT_DESC
,
SORT_REGULAR
,
SORT_NUMERIC
,
SORT_STRING
.
...
Additional arg
's.
成功时返回 TRUE
, 或者在失败时返回 FALSE
。
Example #1 Sorting multiple arrays
<?php
$ar1 = array( 10 , 100 , 100 , 0 );
$ar2 = array( 1 , 3 , 2 , 4 );
array_multisort ( $ar1 , $ar2 );
var_dump ( $ar1 );
var_dump ( $ar2 );
?>
In this example, after sorting, the first array will contain 0, 10, 100, 100. The second array will contain 4, 1, 2, 3. The entries in the second array corresponding to the identical entries in the first array (100 and 100) were sorted as well.
array(4) { [0]=> int(0) [1]=> int(10) [2]=> int(100) [3]=> int(100) } array(4) { [0]=> int(4) [1]=> int(1) [2]=> int(2) [3]=> int(3) }
Example #2 排序多维数组
<?php
$ar = array(
array( "10" , 11 , 100 , 100 , "a" ),
array( 1 , 2 , "2" , 3 , 1 )
);
array_multisort ( $ar [ 0 ], SORT_ASC , SORT_STRING ,
$ar [ 1 ], SORT_NUMERIC , SORT_DESC );
var_dump ( $ar );
?>
本例中在排序后,第一个数组将变成 "10",100,100,11,"a"(被当作字符串以升序排列)。第二个数组将包含 1, 3, "2", 2, 1(被当作数字以降序排列)。
array(2) { [0]=> array(5) { [0]=> string(2) "10" [1]=> int(100) [2]=> int(100) [3]=> int(11) [4]=> string(1) "a" } [1]=> array(5) { [0]=> int(1) [1]=> int(3) [2]=> string(1) "2" [3]=> int(2) [4]=> int(1) } }
Example #3 对数据库结果进行排序
本例中 data 数组中的每个单元表示一个表中的一行。这是典型的数据库记录的数据集合。
例子中的数据如下:
volume | edition -------+-------- 67 | 2 86 | 1 85 | 6 98 | 2 86 | 6 67 | 7
数据全都存放在名为 data 的数组中。这通常是通过循环从数据库取得的结果,例如 mysql_fetch_assoc() 。
<?php
$data [] = array( 'volume' => 67 , 'edition' => 2 );
$data [] = array( 'volume' => 86 , 'edition' => 1 );
$data [] = array( 'volume' => 85 , 'edition' => 6 );
$data [] = array( 'volume' => 98 , 'edition' => 2 );
$data [] = array( 'volume' => 86 , 'edition' => 6 );
$data [] = array( 'volume' => 67 , 'edition' => 7 );
?>
本例中将把 volume 降序排列,把 edition 升序排列。
现在有了包含有行的数组,但是 array_multisort() 需要一个包含列的数组,因此用以下代码来取得列,然后排序。
<?php
// 取得列的列表
foreach ( $data as $key => $row ) {
$volume [ $key ] = $row [ 'volume' ];
$edition [ $key ] = $row [ 'edition' ];
}
// 将数据根据 volume 降序排列,根据 edition 升序排列
// 把 $data 作为最后一个参数,以通用键排序
array_multisort ( $volume , SORT_DESC , $edition , SORT_ASC , $data );
?>
数据集合现在排好序了,结果如下:
volume | edition -------+-------- 98 | 2 86 | 1 86 | 6 85 | 6 67 | 2 67 | 7
Example #4 不区分大小写字母排序
SORT_STRING
和
SORT_REGULAR
都是区分大小写字母的,大写字母会排在小写字母之前。
要进行不区分大小写的排序,就要按照原数组的小写字母拷贝来排序。
<?php
$array = array( 'Alpha' , 'atomic' , 'Beta' , 'bank' );
$array_lowercase = array_map ( 'strtolower' , $array );
array_multisort ( $array_lowercase , SORT_ASC , SORT_STRING , $array );
print_r ( $array );
?>
以上例程会输出:
Array ( [0] => Alpha [1] => atomic [2] => bank [3] => Beta )
【译者注】本函数相当有用,为有助于理解,请再看下面这个例子:
Example #5 名次排列
<?php
$grade = array( "score" => array( 70 , 95 , 70.0 , 60 , "70" ),
"name" => array( "Zhang San" , "Li Si" , "Wang Wu" ,
"Zhao Liu" , "Liu Qi" ));
array_multisort ( $grade [ "score" ], SORT_NUMERIC , SORT_DESC ,
// 将分数作为数值,由高到低排序
$grade [ "name" ], SORT_STRING , SORT_ASC );
// 将名字作为字符串,由小到大排序
var_dump ( $grade );
?>
以上例程会输出:
array(2) { ["score"]=> array(5) { [0]=> int(95) [1]=> string(2) "70" [2]=> float(70) [3]=> int(70) [4]=> int(60) } ["name"]=> array(5) { [0]=> string(5) "Li Si" [1]=> string(6) "Liu Qi" [2]=> string(7) "Wang Wu" [3]=> string(9) "Zhang San" [4]=> string(8) "Zhao Liu" } }
本例中对包含成绩的数组 $grade 按照分数(score)由高到低进行排序,分数相同的人则按照名字(name)由小到大排序。排序后李四 95 分为第一名,赵六 60 分为第五名没有异议。张三、王五和刘七都是 70 分,他们的名次则由其姓名的字母顺序排列,Liu 在前,Wang 在后而 Zhang 在最后。为了区别,三个 70 分分别用了整数,浮点数和字符串来表示,可以在程序输出中清楚地看到它们排序的结果。
[#1] intsystem88 at gmail dot com [2015-10-25 01:03:11]
See (rus): https://intsystem.org/coding/sortirovka-mnogomernyh-massivov-po-klyuchu-na-php/
Simple example:
<?php
$data=array(
array('text'=>'str1', 'year'=>'2010', 'author'=>10),
array('text'=>'str2', 'year'=>'2011', 'author'=>10),
array('text'=>'str3', 'year'=>'2009', 'author'=>20),
array('text'=>'str4', 'year'=>'2010', 'author'=>30),
array('text'=>'str5', 'year'=>'2010', 'author'=>20),
array('text'=>'str6', 'year'=>'2011', 'author'=>10),
array('text'=>'str7', 'year'=>'2011', 'author'=>20),
array('text'=>'str8', 'year'=>'2009', 'author'=>20),
);
$data_year=array();
foreach($data as $key=>$arr){
$data_year[$key]=$arr['year'];
}
for($i=0; $i<100000; $i++){
$data_tmp=$data;
array_multisort($data_year, SORT_NUMERIC, $data_tmp);
}
?>
[#2] nospam at nospam dot com [2015-10-23 22:30:18]
Super easy and simple way to sort a keyed multiarray while maintaining all associative keys, including numeric!
Preserves the original multiarray order if the sorting values are equal.
<?php
// sorts multiarray by a subarray value while preserving all keys, also preserves original order when the sorting values match
function maSort($ma = '', $sortkey = '', $sortorder = 1) { // sortorder: 1=asc, 2=desc
if ($ma && is_array($ma) && $sortkey) { // confirm inputs
foreach ($ma as $k=>$a) $temp["$a[$sortkey]"][$k] = $a; // temp ma with sort value, quotes convert key to string in case numeric float
if ($sortorder == 2) { // descending
krsort($temp);
} else { // ascending
ksort($temp);
}
$newma = array(); // blank output multiarray to add to
foreach ($temp as $sma) $newma += $sma; // add sorted arrays to output array
unset($ma, $sma, $temp); // release memory
return $newma;
}
}
?>
[#3] nospam at nospam dot com [2015-10-23 19:34:19]
Super easy and simple way to sort a keyed multiarray while maintaining all associative keys including numeric. This is awesome!
<?php
// returns sorted multiarray by its subarray's sortkey in given sortorder while keeping all keys
function maSort($ma = '', $sortkey = '', $sortorder = 1) { // sortorder: 1=asc, 2=desc
if ($ma && is_array($ma) && $sortkey) { // confirm inputs
foreach ($ma as $k=>$a) $temp[$k] = $a[$sortkey]; // save temp array to be sorted
if ($sortorder == 2) { // descending
arsort($temp);
} else {
asort($temp); // ascending
}
$newma = array_replace($temp, $ma); // combine to keep order of sorted array but with original $ma info
unset($ma, $temp); // release memory
return $newma;
}
}
?>
[#4] matt at wennersten dot org [2015-07-29 09:09:48]
Many users have contributed nifty wrapper functions for generalizing array_multisort. However, some of us may just want a simple example that illustrates how to sort an arbitrary multi-dimensional array, such as a database result set, on a named field.
Consider an array of voice recordings (Clip objects) that are stored on a file system, and referenced via a database table:
$fetchClipQuery = "SELECT * from voiceclips";
if ( !$result = $this->db->query($fetchClipQuery) ) {
$errormessage = $this->db->errno;
$errormessage .= $this->db->error;
} else {
while($row = $result->fetch_assoc()){
$clip = new Clip();
$clip->populate($row['clipURL']);
$clips[] = array("speaker"=>$row['speaker'],"duration"=>$row['duration'],"clip"=>$clip);
}
//we now have an array called clips[] that looks like this:
array("speaker"=>"Obama","duration"=>"22:00","clip"=>...<some arbitrary object>...);
//suppose we want to sort the array by speaker
$sortkeyname = "speaker";
//do the sort
$sortkeyarray = array();
foreach ($clips as $key => $row){
$sortkeyarray[$key] = $row[$sortkeyname];
}
array_multisort($sortkeyarray, SORT_DESC, $clips);
//suppose we want to sort the array by duration
$sortkeyname = "duration";
//do the sort
$sortkeyarray = array();
foreach ($clips as $key => $row){
$sortkeyarray[$key] = $row[$sortkeyname];
}
array_multisort($sortkeyarray, SORT_DESC, $clips);
...etc.
[#5] jcharpentier at darkmira dot fr [2014-02-23 17:11:32]
There is a lack of precision for the second example :
Example #2 Sorting multi-dimensional array
The explanation is :
"In this example, [...] The second will contain 1, 3, "2", 2, 1 (sorted as numbers, in descending order). "
This could be misunderstood cause a sort as numbers in descending order will be 1, 1, "2", 2, 3.
My proposal is as follows (in a best english should be great ^^) :
"In this example, [...] The second will contain 1, 3, "2", 2, 1 (sorted as well as first one, except for values 3 and "2" sorted as numbers, in descending order). Because they are corresponding to the identical entries in the first array (100 and 100) which couldn't be sorted at first time."
[#6] Robert C [2014-01-09 12:11:07]
Hi,
I would like to see the next code snippet to be added to http://nl3.php.net/array_multisort
Purpose: Sort a 2-dimensional array on some key(s)
Advantage of function:
- uses PHP's array_multisort function for sorting;
- it prepares the arrays (needed by array_multisort) for you;
- allows the sort criteria be passed as a separate array (It is possible to use sort order and flags.);
- easy to set/overwrite the way strings are sorted (case insensitive instead of case sensitive, which is PHP's default way of sorting);
- performs excellent
function MultiSort($data, $sortCriteria, $caseInSensitive = true)
{
if( !is_array($data) || !is_array($sortCriteria))
return false;
$args = array();
$i = 0;
foreach($sortCriteria as $sortColumn => $sortAttributes)
{
$colList = array();
foreach ($data as $key => $row)
{
$convertToLower = $caseInSensitive && (in_array(SORT_STRING, $sortAttributes) || in_array(SORT_REGULAR, $sortAttributes));
$rowData = $convertToLower ? strtolower($row[$sortColumn]) : $row[$sortColumn];
$colLists[$sortColumn][$key] = $rowData;
}
$args[] = &$colLists[$sortColumn];
foreach($sortAttributes as $sortAttribute)
{
$tmp[$i] = $sortAttribute;
$args[] = &$tmp[$i];
$i++;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return end($args);
}
Usage:
//Fill an array with random test data
define('MAX_ITEMS', 15);
define('MAX_VAL', 20);
for($i=0; $i < MAX_ITEMS; $i++)
$data[] = array('field1' => rand(1, MAX_VAL), 'field2' => rand(1, MAX_VAL), 'field3' => rand(1, MAX_VAL) );
//Set the sort criteria (add as many fields as you want)
$sortCriteria =
array('field1' => array(SORT_DESC, SORT_NUMERIC),
'field3' => array(SORT_DESC, SORT_NUMERIC)
);
//Call it like this:
$sortedData = MultiSort($data, $sortCriteria, true);
[#7] Patrick Adrichem [2013-10-17 08:08:32]
If you do not have PHP 5.4 installed yet and you cannot use SORT_NATURAL. This function sorts arrays natural multi-dimensional based on key value
this function can be used for arrays as
array ( name => array( key => value ) )
and
array( name => value ).
arrays as array( name => array( key => value), name => value) are not supported.
<?php
static function natcasesortRecursive(&$aArray)
{
$bHasArrays = false;
foreach ($aArray as $sKey => &$mValue)
{
if (true === is_array($mValue))
{
self::natcasesortRecursive($mValue);
$bHasArrays = true;
}
}
if (true === $bHasArrays)
{
uksort($aArray, 'strnatcasecmp');
}
else
{
natcasesort($aArray);
}
}
?>
[#8] Magento-User [2013-10-11 15:25:00]
When sorting an array of (complex) objects, this function can give you a "Fatal error: Nesting level too deep" since it directly compares elements in later arrays if the elements in earlier ones compare equal. This can be worked around with the Flag-Parameter:
<?php
$sortKeys = array_map($extractKey, $lotsOfComplexObjects);
array_multisort($sortKeys, $lotsOfComplexObjects, SORT_ASC, SORT_NUMERIC);
?>
I'm replacing an 'uasort()'-call which is significantly slower since it leads to a lot of calls to the comparison-function but most of the objects involved are recursive.
If this 'trick' gives a wrong order, you need a better key.
[#9] srijishks at gmail dot com [2013-04-23 06:24:19]
The size should be same for all sub arrays
[#10] plugboard at web dot de [2012-09-04 14:56:46]
multisort an Array of Objects:
example object [$object with array of objects]: (class: test)
----------------------------------
test Object (
[Artikel] => Array (
[0] => test Object (
[id] => 1
[title] => CCCC
)
[1] => test Object (
[id] => 2
[title] => AAAA
)
[2] => test Object (
[id] => 3
[title] => DDDD
)
[3] => test Object (
[id] => 4
[title] => BBBB
)
)
)
----------------------------------
Simple PHP function: sort_arr_of_obj()
<?php
// --------------------------------------
function sort_arr_of_obj($array, $sortby, $direction='asc') {
$sortedArr = array();
$tmp_Array = array();
foreach($array as $k => $v) {
$tmp_Array[] = strtolower($v->$sortby);
}
if($direction=='asc'){
asort($tmp_Array);
}else{
arsort($tmp_Array);
}
foreach($tmp_Array as $k=>$tmp){
$sortedArr[] = $array[$k];
}
return $sortedArr;
}
// --------------------------------------
?>
example call:
----------------------------------
<?php
$sorted->Artikel = sort_arr_of_obj($object->Artikel,'title','asc');
?>
example result: $sorted (class: test)
----------------------------------
test Object (
[Artikel] => Array (
[0] => test Object (
[id] => 2
[title] => AAAA
)
[1] => test Object (
[id] => 4
[title] => BBBB
)
[2] => test Object (
[id] => 1
[title] => CCCC
)
[3] => test Object (
[id] => 3
[title] => DDDD
)
)
)
-------------------------
:)
[#11] rnacken at gmail dot com [2012-02-11 23:59:25]
When I was working on a search engine, that had to order the results in PHP by multiple arguments, I got stuck on the issue of multisort erasing your (numeral) indexes for a while. Sometimes, it is important to keep these indexes intact. In my case, the indexes were IDs and the values were a percentage of how relevant the object was, considering an earlier query.
e.g: $searchResult = (23 => 0.3,
102 => 0.5,
11 => 0.5,
340 => 0.5,
10 => 0.9);
I wanted to use array_multisort to first sort DESC on the IDs, and then on the values DESC. i.e. I wanted to show the highest values first, but in case of two (or more) objects with the same value, the higher ID would be shown first.
e.g: $searchResult = (10 => 0.9,
340 => 0.5,
102 => 0.5,
11 => 0.5,
23 => 0.3);
The easiest way to do this, I think, is:
<?php
// create a 2-deep array with the values and keys of $searchResult
$array = array(
$searchResult,
array_keys($searchResult)
);
// use multisort, first on the values, then on the keys. This will erase the indexes in the $searchResult array
array_multisort($array[0], SORT_DESC, $array[1], SORT_DESC);
// get the ordered keys back in the $searchResult array
$searchResult = array_combine($array[1], $array[0]);
unset($array); //clear some memory
?>
[#12] nick ([AT]) nickyost ([DOT]) com [2011-09-15 15:36:20]
USort function can be used to sort multidimensional arrays with almost no work whatsoever by using the individual values within the custom sort function.
This function passes the entire child element even if it is not a string. If it is an array, as would be the case in multidimensional arrays, it will pass the whole child array as one parameter.
Therefore, do something elegant like this:
<?php
// Sort the multidimensional array
usort($results, "custom_sort");
// Define the custom sort function
function custom_sort($a,$b) {
return $a['some_sub_var']>$b['some_sub_var'];
}
?>
This does in 4 lines what other functions took 40 to 50 lines to do. This does not require you to create temporary arrays or anything. This is, for me, a highly preferred solution over this function.
Hope it helps!
[#13] info at ichier dot de [2011-07-28 08:59:07]
if you want to sort an array by columns, this is the function to do it.
<?php
function array_csort() { //coded by Ichier2003
$args = func_get_args();
$marray = array_shift($args);
$msortline = 'return(array_multisort(';
foreach ($args as $arg) {
$i++;
if (is_string($arg)) {
foreach ($marray as $row) {
$sortarr[$i][] = $row[$arg];
}
} else {
$sortarr[$i] = $arg;
}
$msortline .= '$sortarr['.$i.'],';
}
$msortline .= '$marray));';
eval($msortline);
return $marray;
}
?>
[#14] thierryzo at hotmail dot fr [2011-06-29 02:27:40]
//A very simple way to sort arrays with this kind of structure.
<?php
$myArray =array(
array("NUMCIE" => "001","REF" => "RXL","COLOR" => "RED","L1" => 4),
array("NUMCIE" => "001","REF" => "RXL","COLOR" => "BLUE","L1" => 6),
array("NUMCIE" => "001","REF" => "RHQ","COLOR" => "RED","L1" => 4),
array("NUMCIE" => "002","REF" => "RXL","COLOR" => "YELLOW","L1" => 8));
foreach($myArray as $c=>$key) {
$sort_numcie[] = $key['NUMCIE'];
$sort_ref[] = $key['REF'];
$sort_color[] = $key['COLOR'];
}
array_multisort($sort_numcie, SORT_ASC, $sort_ref, SORT_STRING, $myArray);
print_r($myArray);
?>
//Result array
Array
(
[0] => Array
(
[NUMCIE] => 001
[REF] => RHQ
[COLOR] => RED
[L1] => 4
)
[1] => Array
(
[NUMCIE] => 001
[REF] => RXL
[COLOR] => BLUE
[L1] => 6
)
[2] => Array
(
[NUMCIE] => 001
[REF] => RXL
[COLOR] => RED
[L1] => 4
)
[3] => Array
(
[NUMCIE] => 002
[REF] => RXL
[COLOR] => YELLOW
[L1] => 8
)
)
[#15] Jaak Tamre [2011-03-22 06:42:58]
I had a problem with sorting SimpleXMLElement list. I found a nice short solution.
I have an array of ticket objects: $ticketList = $xml->Tickets;
<?php
// Sort by ValidOnDate
$tickets = array();
$valid = array();
foreach ($ticketList as $row) {
$tickets[] = $row;
$valid[] = DateHandler::parseDate($row->ValidOnDate);
}
array_multisort($valid, SORT_DESC, $tickets);
?>
Just make an array of object items you want to sort by and a new array for the same objects which will be reordered like the first array.
Ps: my own parseDate(date) returns unix timestamp for different date formats.
[#16] jimpoz at jimpoz dot com [2010-10-21 14:26:26]
I came up with an easy way to sort database-style results. This does what example 3 does, except it takes care of creating those intermediate arrays for you before passing control on to array_multisort().
<?php
function array_orderby()
{
$args = func_get_args();
$data = array_shift($args);
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
?>
The sorted array is now in the return value of the function instead of being passed by reference.
<?php
$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);
// Pass the array, followed by the column names and sort flags
$sorted = array_orderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC);
?>
[#17] zequez at gmail dot com [2010-05-06 15:19:32]
Easiest way I find out to sort an entire multidimensional array by one element of it:
<?php
$multiArray = Array(
Array("id" => 1, "name" => "Defg"),
Array("id" => 2, "name" => "Abcd"),
Array("id" => 3, "name" => "Bcde"),
Array("id" => 4, "name" => "Cdef"));
$tmp = Array();
foreach($multiArray as &$ma)
$tmp[] = &$ma["name"];
array_multisort($tmp, $multiArray);
foreach($multiArray as &$ma)
echo $ma["name"]."<br/>";
?>
^-^
[#18] alexander dot v at zend dot com [2010-01-20 03:42:28]
array_multisort works normally in php 5.3, but it forces arguments to be references.
It doesn't make differences for common array_multisort() usage, but makes "problems" for sorting variable number of arrays where call_user_func_array() function is involved.
So all sorting arrays have to be collected into new one as a references to array variables:
<?php
$sortArgs = array();
for (...) {
...
$sortArgs[] = &$valuesArray;
...
}
call_user_func_array('array_multisort', $sortArgs);
?>
This (requiring arguments to be a reference) is not actually a problem since source array will not be sorted otherwise.
Important note!
Don't forget to destroy $valuesArray variable if you use it over each array_multisort() argument processing iteration.
If you don't do it, all array_multisort() arguments will contain the same array:
<?php
for (...) {
...
$sortArgs[] = &$valuesArray;
unset($valuesArray);
...
}
?>
And the last important thing :)
Collect sorting arrays somewhere. PHP 5.3 will transfer reference into value (when $valuesArray is destroyed) and you will get "Parameter 1 to array_multisort() expected to be a reference, value given" warning again otherwise.
Final code should look like this:
<?php
$sortArgs = array();
$sortFieldValues = array();
for (...) {
...
$sortFieldValues[] = &$valuesArray;
$sortArgs[] = &$valuesArray;
unset($valuesArray);
...
}
call_user_func_array('array_multisort', $sortArgs);
?>
[#19] d_inkubus at yahoo dot com [2009-12-21 15:33:26]
Update to array_msort()--in PHP 5.3 it won't work.
The solution is to replace the array_merge($params, $order) with the following code snippet:
<?php
$order=(array)$order;
foreach($order as $order_element)
{
$params[]=&$order_element;
}
?>
Full code to array_msort():
<?php
function array_msort($array, $cols)
{
$colarr = array();
foreach ($cols as $col => $order)
{
$colarr[$col] = array();
foreach ($array as $k => $row)
{
$colarr[$col]['_'.$k] = strtolower($row[$col]);
}
}
$params = array();
foreach ($cols as $col => $order)
{
$params[] =&$colarr[$col];
$order=(array)$order;
foreach($order as $order_element)
{
//pass by reference, as required by php 5.3
$params[]=&$order_element;
}
}
call_user_func_array('array_multisort', $params);
$ret = array();
$keys = array();
$first = true;
foreach ($colarr as $col => $arr)
{
foreach ($arr as $k => $v)
{
if ($first)
{
$keys[$k] = substr($k,1);
}
$k = $keys[$k];
if (!isset($ret[$k]))
{
$ret[$k] = $array[$k];
}
$ret[$k][$col] = $array[$k][$col];
}
$first = false;
}
return $ret;
}
?>
For further reference, see these bug reports:
http://bugs.php.net/bug.php?id=49069
http://bugs.php.net/bug.php?id=49241
[#20] s dot i dot g at gmx dot com [2009-07-10 06:21:42]
simple dns mx record sorting
<?php
//getting domain name
list($user, $domain) = split('[@]', $email);
getmxrr($domain, $mx_server, $mx_weight);
//sorting
for($i = 0; $i < count($mx_server); $i++)
{
$mx[$i] = array
(
"server" => $mx_server[$i],
"weight" => $mx_weight[$i],
);
}
array_multisort($mx_weight, SORT_ASC, $mx_server, SORT_ASC, $mx);
//display result
print_r($mx);
//usage
$server = $mx[0]["server"];
?>
[#21] cagret at gmail dot com [2009-06-21 03:38:19]
Update to array_msort(): instead of eval() using call_user_func_array(). If we get column sorting via $_GET it would be a serious security hole.
Now it also accepts multiple options for each column:
<?php
$arr2 = array_msort($arr1, array('name'=>array(SORT_DESC,SORT_REGULAR), 'cat'=>SORT_ASC));
?>
Btw. this function is automatically case-insensitive, as you can see use of strtolower().
<?php
function array_msort($array, $cols)
{
$colarr = array();
foreach ($cols as $col => $order) {
$colarr[$col] = array();
foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
}
$params = array();
foreach ($cols as $col => $order) {
$params[] =& $colarr[$col];
$params = array_merge($params, (array)$order);
}
call_user_func_array('array_multisort', $params);
$ret = array();
$keys = array();
$first = true;
foreach ($colarr as $col => $arr) {
foreach ($arr as $k => $v) {
if ($first) { $keys[$k] = substr($k,1); }
$k = $keys[$k];
if (!isset($ret[$k])) $ret[$k] = $array[$k];
$ret[$k][$col] = $array[$k][$col];
}
$first = false;
}
return $ret;
}
?>
[#22] cagret at gmail dot com [2009-06-20 12:16:54]
A more inuitive way of sorting multidimensional arrays using array_msort() in just one line, you don't have to divide the original array into per-column-arrays:
<?php
$arr1 = array(
array('id'=>1,'name'=>'aA','cat'=>'cc'),
array('id'=>2,'name'=>'aa','cat'=>'dd'),
array('id'=>3,'name'=>'bb','cat'=>'cc'),
array('id'=>4,'name'=>'bb','cat'=>'dd')
);
$arr2 = array_msort($arr1, array('name'=>SORT_DESC, 'cat'=>SORT_ASC));
debug($arr1, $arr2);
arr1:
0:
id: 1 (int)
name: aA (string:2)
cat: cc (string:2)
1:
id: 2 (int)
name: aa (string:2)
cat: dd (string:2)
2:
id: 3 (int)
name: bb (string:2)
cat: cc (string:2)
3:
id: 4 (int)
name: bb (string:2)
cat: dd (string:2)
arr2:
2:
id: 3 (int)
name: bb (string:2)
cat: cc (string:2)
3:
id: 4 (int)
name: bb (string:2)
cat: dd (string:2)
0:
id: 1 (int)
name: aA (string:2)
cat: cc (string:2)
1:
id: 2 (int)
name: aa (string:2)
cat: dd (string:2)
function array_msort($array, $cols)
{
$colarr = array();
foreach ($cols as $col => $order) {
$colarr[$col] = array();
foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
}
$eval = 'array_multisort(';
foreach ($cols as $col => $order) {
$eval .= '$colarr[\''.$col.'\'],'.$order.',';
}
$eval = substr($eval,0,-1).');';
eval($eval);
$ret = array();
foreach ($colarr as $col => $arr) {
foreach ($arr as $k => $v) {
$k = substr($k,1);
if (!isset($ret[$k])) $ret[$k] = $array[$k];
$ret[$k][$col] = $array[$k][$col];
}
}
return $ret;
}
?>
[#23] m dot michalczyk at gmail dot com [2009-05-16 03:45:22]
Here is useful example based on za at byza dot it solution to sort multidimensional objects by any dimension.
za at byza dot it
<?php
class person{
function __construct($firstName, $lastName, $title, $position){
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->title = new title($title);
$this->position = new position($position);
}
}
class title{
function __construct($name){
$this->name = $name;
}
}
class position{
function __construct($name){
$this->name = $name;
}
}
$array[] = new person('Piotr', 'Sobiepanek', 'b', 'b');
$array[] = new person('Piotr', 'Kowalski', 'b', 'a');
$array[] = new person('Piotr', 'Michalski', 'a', 'a');
$array[] = new person('Jozef', 'Smietana', 'a', 'b');
$array[] = new person('Jozef', 'Cmietana', 'a', 'b');
$array[] = new person('Marcin', 'Kondraciuk', 'c', 'b');
$array[] = new person('Maksym', 'Kondraciuk', 'c', 'd');
$array[] = new person('Ambrozy', 'Kondraciuk', 'c', 'd');
$array[] = new person('Alojzy', 'Kondraciuk', 'c', 'd');
array_sort($array, 'title->name', 'position->name', 'lastName');
print_r($array);
function hod(&$base, $path){
$keys = explode("->", $path);
$keys[0] = str_replace('$', '', $keys[0]);
$expression = '$ret = ';
$expression.= '$';
foreach ($keys as $key){
if (++$licz == 1){
$expression.= 'base->';
} else {
$expression.= $key.'->';
}
}
$expression = substr($expression, 0, -2);
$expression.= ';';
eval($expression);
return $ret;
}
function array_sort_func($a,$b=NULL) {
static $keys;
if($b===NULL) return $keys=$a;
foreach($keys as $k) {
if($k[0]=='!') {
$k=substr($k,1);
if(hod($a, '$a->'.$k)!==hod($b, '$b->'.$k)) {
return strcmp(hod($b, '$b->'.$k),hod($a, '$a->'.$k));
}
}
else if(hod($a, '$a->'.$k)!==hod($b, '$b->'.$k)) {
return strcmp(hod($a, '$a->'.$k),hod($b, '$b->'.$k));
}
}
return 0;
}
function array_sort(&$array) {
if(!$array) return $keys;
$keys=func_get_args();
array_shift($keys);
array_sort_func($keys);
usort($array,"array_sort_func");
}
?>
[#24] za at byza dot it [2009-04-27 10:08:25]
I wrote a function to sort a multidimensional array by multiple columns in ascending and descending order.
Sample array:
<?php
$my_array=array(
array('id'=>1, 'surname'=>'rossi', 'name'=>'mario', 'group'=>'admin'),
array('id'=>2, 'surname'=>'rossi', 'name'=>'giovanni', 'group'=>'user'),
array('id'=>3, 'surname'=>'verdi', 'name'=>'luigi', 'group'=>'user'),
array('id'=>4, 'surname'=>'verdi', 'name'=>'franco', 'group'=>'guest'),
array('id'=>5, 'surname'=>'bianchi', 'name'=>'mario', 'group'=>'guest')
);
?>
Example:
<?php array_sort($my_array,'!group','surname'); ?>
Output: sort the array DESCENDING by group and then ASCENDING by surname. Notice the use of ! to reverse the sort order. Rows order will be: 2,3,5,4,1
The function code:
<?php
function array_sort_func($a,$b=NULL) {
static $keys;
if($b===NULL) return $keys=$a;
foreach($keys as $k) {
if(@$k[0]=='!') {
$k=substr($k,1);
if(@$a[$k]!==@$b[$k]) {
return strcmp(@$b[$k],@$a[$k]);
}
}
else if(@$a[$k]!==@$b[$k]) {
return strcmp(@$a[$k],@$b[$k]);
}
}
return 0;
}
function array_sort(&$array) {
if(!$array) return $keys;
$keys=func_get_args();
array_shift($keys);
array_sort_func($keys);
usort($array,"array_sort_func");
}
?>
[#25] mech.cx [2009-03-28 12:04:46]
I was (as near everyone here :-) looking to sort 2-dimensional arrays by certain fields in the associative sub-arrays.
What I didn't like about the documentation examples is that you need to loop through the input array to create sub arrays first, then use those in the function call.
"php a-t-the-r-a-t-e chir.ag" (http://www.php.net/manual/en/function.array-multisort.php#60401) wrote a quite cunning wrapper function, I rewrote it slightly, changing variable names and adding comments (for my sanity :-) mostly.
One snag I found: the input array is passed to array_multisort as last argument, but the changed array is not the one that is returned. Passing it by reference fixed that. This seems to be caused by the whole thing sitting inside the call_user_func_array, as shown below.
<?php
$points = array(1, 5, 2, 2);
$names = array('peter', 'mike', 'john Zoo', 'john Ab');
$source = array (
array ( 'points' => 1, 'name' => 'Peter'),
array ( 'points' => 5, 'name' => 'Mike'),
array ( 'points' => 2, 'name' => 'John Zoo'),
array ( 'points' => 2, 'name' => 'John Ab')
);
call_user_func_array('array_multisort', array($points, SORT_DESC, SORT_NUMERIC, $names, SORT_ASC, SORT_STRING, $source)); // doesn't work
print_r($source);
call_user_func_array('array_multisort', array($points, SORT_DESC, SORT_NUMERIC, $names, SORT_ASC, SORT_STRING, &$source)); // works!
print_r($source);
// Call like arrayColumnSort('points', SORT_DESC, SORT_NUMERIC, 'name', SORT_ASC, SORT_STRING, $source);
// Slightly adapted from http://www.php.net/manual/en/function.array-multisort.php#60401
// arrayColumnSort(string $field, [options, ], string $field2, [options, ], .... , $array) /
//____________________
// arrayColumnSort() /
function arrayColumnSort() {
$args = func_get_args();
$array = array_pop($args);
if (! is_array($array)) return false;
// Here we'll sift out the values from the columns we want to sort on, and put them in numbered 'subar' ("sub-array") arrays.
// (So when sorting by two fields with two modifiers (sort options) each, this will create $subar0 and $subar3)
foreach($array as $key => $row) // loop through source array
foreach($args as $akey => $val) // loop through args (fields and modifiers)
if(is_string($val)) // if the arg's a field, add its value from the source array to a sub-array
${"subar$akey"}[$key] = $row[$val];
// $multisort_args contains the arguments that would (/will) go into array_multisort(): sub-arrays, modifiers and the source array
$multisort_args = array();
foreach($args as $key => $val)
$multisort_args[] = (is_string($val) ? ${"subar$key"} : $val);
$multisort_args[] = &$array; // finally add the source array, by reference
call_user_func_array("array_multisort", $multisort_args);
return $array;
}
?>
[#26] frank at overdrunk dot net [2009-01-14 14:38:16]
I had a function to make a sort on a 2D array and I wanted to sort an array using a column that usualy contains numeric values but also strings.
Lets say we have this array :
Array (
[0] => Array ( "name" = "12000" ),
[1] => Array ( "name" = "113" ),
[2] => Array ( "name" = "test 01" ),
[3] => Array ( "name" = "15000 tests" ),
[4] => Array ( "name" = "45" ),
[5] => Array ( "name" = "350" ),
[6] => Array ( "name" = "725" ),
[7] => Array ( "name" = "hello" )
}
SORT_STRING whould have returned me this :
Array ( // Numeric values are not correctly sorted
[0] => Array ( "name" = "113" ),
[1] => Array ( "name" = "12000" ),
[2] => Array ( "name" = "15000 tests" ),
[3] => Array ( "name" = "350" ),
[4] => Array ( "name" = "45" ),
[5] => Array ( "name" = "725" ),
[6] => Array ( "name" = "hello" ),
[7] => Array ( "name" = "test 01" )
}
SORT_NUMERIC would have returned me this :
Array ( // String values are not sorted, just in the same order
[0] => Array ( "name" = "test 01" ),
[1] => Array ( "name" = "hello" ),
[2] => Array ( "name" = "45" ),
[3] => Array ( "name" = "113" ),
[4] => Array ( "name" = "350" ),
[5] => Array ( "name" = "725" ),
[6] => Array ( "name" = "12000" ),
[7] => Array ( "name" = "15000 tests" ),
}
So I've made this hybrid code which combines the best of both worlds by merging content sorted either way according to the first caracter of the string:
<?php
function sort_col($table, $colname) {
$tn = $ts = $temp_num = $temp_str = array();
foreach ($table as $key => $row) {
if(is_numeric(substr($row[$colname], 0, 1))) {
$tn[$key] = $row[$colname];
$temp_num[$key] = $row;
}
else {
$ts[$key] = $row[$colname];
$temp_str[$key] = $row;
}
}
unset($table);
array_multisort($tn, SORT_ASC, SORT_NUMERIC, $temp_num);
array_multisort($ts, SORT_ASC, SORT_STRING, $temp_str);
return array_merge($temp_num, $temp_str);
}
?>
It would return something like this :
Array (
[2] => Array ( "name" = "45" ),
[3] => Array ( "name" = "113" ),
[4] => Array ( "name" = "350" ),
[5] => Array ( "name" = "725" ),
[6] => Array ( "name" = "12000" ),
[7] => Array ( "name" = "15000 tests" ),
[1] => Array ( "name" = "hello" ),
[0] => Array ( "name" = "test 01" ),
}
[#27] Zbigniew Heintze http://bigweb.pl [2008-11-26 23:36:10]
<?php
function sortDbResult(array $data ) {
$_argList = func_get_args();
$_data = array_shift($_argList);
if (empty($_data)) {
return $_data;
}
$_max = count($_argList);
$_params = array();
$_cols = array();
$_rules = array();
for ($_i = 0; $_i < $_max; $_i += 3)
{
$_name = (string) $_argList[$_i];
if (!in_array($_name, array_keys(current($_data)))) {
continue;
}
if (!isset($_argList[($_i + 1)]) || is_string($_argList[($_i + 1)])) {
$_order = SORT_ASC;
$_mode = SORT_REGULAR;
$_i -= 2;
} else if (3 > $_argList[($_i + 1)]) {
$_order = SORT_ASC;
$_mode = $_argList[($_i + 1)];
$_i--;
} else {
$_order = $_argList[($_i + 1)] == SORT_ASC ? SORT_ASC : SORT_DESC;
if (!isset($_argList[($_i + 2)]) || is_string($_argList[($_i + 2)])) {
$_mode = SORT_REGULAR;
$_i--;
} else {
$_mode = $_argList[($_i + 2)];
}
}
$_mode = $_mode != SORT_NUMERIC
? $_argList[($_i + 2)] != SORT_STRING ? SORT_REGULAR : SORT_STRING
: SORT_NUMERIC;
$_rules[] = array('name' => $_name, 'order' => $_order, 'mode' => $_mode);
}
foreach ($_data as $_k => $_row) {
foreach ($_rules as $_rule) {
if (!isset($_cols[$_rule['name']])) {
$_cols[$_rule['name']] = array();
$_params[] = &$_cols[$_rule['name']];
$_params[] = $_rule['order'];
$_params[] = $_rule['mode'];
}
$_cols[$_rule['name']][$_k] = $_row[$_rule['name']];
}
}
$_params[] = &$_data;
call_user_func_array('array_multisort', $_params);
return $_data;
}
?>
[#28] oOo at OoO dot com [2008-11-10 00:58:52]
Since the manual doesn't specify so, I want to point out that the SORT_NUMERIC flag does also work correctly if the values are floating point numbers.
Just don't forget to also add the respective SORT_ASC or SORT_DESC flag :)
[#29] matt at idizinc dot com [2008-10-23 11:47:06]
I looked on some forms for an answer to this simple problem and couldn't find one so I came up with a solution that may help in some situations.
How do you sort an array by a field in that array and resolve numeric ties randomly?
Code:
<?php
foreach($list as $temp_list)
{
$sort_aux[] = ($temp_list['column_to_sort_by']+(rand(1, 9)/10));
}
array_multisort($sort_aux, SORT_NUMERIC, $list);
?>
Example:
$list[]=array('name'=>'Tom', 'score'=>3);
$list[]=array('name'=>'Sam', 'score'=>3);
$list[]=array('name'=>'Joey', 'score'=>1);
Explanation:
I took an existing example found above that shows how to sort an array by one of it's columns/fields.
I just added: "+(rand(1,9)/10)" To randomly add .1 through .9 to their score to resolve the tie. (Obviously this specific example only works if you're sorting by an integer... so you may need to modify it to suit your needs.)
Hope this helps someone.
[#30] isp dot php at spspft dot de [2008-10-19 05:44:04]
I would like to report a kind of confusion that arose with the message
Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of array_multisort(). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file...
from a line like this:
array_multisort (&$keyarr, &$arr );// sort against this keys
This message is not easily switched off by changing the error reporting level because it's produced at parsinig time -- not execution time.
I think this message is misleading because the arguments are passed by reference ANYWAY in array_multisort.
Anybody encountering this message should know that nothing has to be done, except deleting the ampersands (&).
I was tricked by this message because of couse I wanted to have the *sorted* array back. And couldn't find the ini file nor the declaration of array_multisort.
I think in this description of array_multisort the call by reference should be listed in the definition.
Hope this helps someone
[#31] seiffs_at_centrum-dot-cz [2008-08-18 08:53:06]
There have to be two corrections to the php_multisort($data,$keys)
// Sort Expression
$i=0;
$sort=''; //here
foreach ($keys as $k){
if($i>0){$sort.=',';}
$sort.='$cols[\''.$k['key'].'\']'; //and here
if($k['sort']){$sort.=',SORT_'.strtoupper($k['sort']);}
if($k['type']){$sort.=',SORT_'.strtoupper($k['type']);}
$i++;
}
[#32] php {dot} net [arrt] sebble.com [2008-05-11 02:16:45]
I was requiring a PHP function a sort my array data as part of an SQL interpreter for PHP arrays. This is the code I came up with. and works wonderfully.
I hope this helps somebody. If anyone uses this, let me know what you think, if there are any problems with it...
<?php
## ##
## PHPMultiSort ##
## ##
// Takes:
// $data, multidim array
// $keys, array(array(key=>col1, sort=>desc), array(key=>col2, type=>numeric))
function php_multisort($data,$keys){
// List As Columns
foreach ($data as $key => $row) {
foreach ($keys as $k){
$cols[$k['key']][$key] = $row[$k['key']];
}
}
// List original keys
$idkeys=array_keys($data);
// Sort Expression
$i=0;
foreach ($keys as $k){
if($i>0){$sort.=',';}
$sort.='$cols['.$k['key'].']';
if($k['sort']){$sort.=',SORT_'.strtoupper($k['sort']);}
if($k['type']){$sort.=',SORT_'.strtoupper($k['type']);}
$i++;
}
$sort.=',$idkeys';
// Sort Funct
$sort='array_multisort('.$sort.');';
eval($sort);
// Rebuild Full Array
foreach($idkeys as $idkey){
$result[$idkey]=$data[$idkey];
}
return $result;
}
###############
// Example Data
$_DATA['table1'][] = array("name" => "Sebastian", "age" => 18, "male" => true);
$_DATA['table1'][] = array("name" => "Lawrence", "age" => 16, "male" => true);
$_DATA['table1'][] = array("name" => "Olivia", "age" => 10, "male" => false);
$_DATA['table1'][] = array("name" => "Dad", "age" => 50, "male" => true);
$_DATA['table1'][] = array("name" => "Mum", "age" => 40, "male" => false);
$_DATA['table1'][] = array("name" => "Sebastian", "age" => 56, "male" => true);
$_DATA['table1'][] = array("name" => "Lawrence", "age" => 19, "male" => true);
$_DATA['table1'][] = array("name" => "Olivia", "age" => 24, "male" => false);
$_DATA['table1'][] = array("name" => "Dad", "age" => 10, "male" => true);
$_DATA['table1'][] = array("name" => "Mum", "age" => 70, "male" => false);
###############
$res=php_multisort($_DATA['table1'], array(array('key'=>'name'),array('key'=>'age','sort'=>'desc')))
var_dump($res);
?>
[#33] joopm at hotmail dot com [2008-04-10 04:50:27]
@ scott at bartoncomputer dot com
You could also reference the array (if you wanted the original array in the object sorted):
array_multisort($position, SORT_DESC, &$clsVar->data);
Regards, Chr.
[#34] glenn at freebsd dot nl [2007-11-29 10:49:27]
To sort a nested array by column (key/index):
Example: two entries in the nested array:
firstarray[0]['adres'] = "adres1"
firstarray[0]['email'] = "email2"
firstarray[1]['adres'] = "adres2"
firstarray[1]['email'] = "email1"
-----------------------------------------
Without code: output would put adres1/email2 on top
-----------------------------------------
foreach($firstarray as $sortarray)
{
$column[] = $sortarray['email'];
array_multisort($column, SORT_ASC, $firstarray);
}
-----------------------------------------
With code: output would put adres2/email1 on top
[#35] scott at bartoncomputer dot com [2007-05-03 10:18:07]
I didn't see this noted anywhere, so I figured I'd put in a little comment regarding arrays located inside classes. For instance:
class abc
{
var $data;
}
The following code does not act as expected:
$clsVar =& new abc();
foreach ($clsVar->data as $key => $row)
{
$position[$key] = $key;
}
array_multisort($position, SORT_DESC, $clsVar->data);
While I realize this could much easily be acheived using ksort(), this is merely a much more simple example of this behaviour. The exerpt above comes from a much more complicated sort using multi-scripted arrays.
Anyway the only way I could find to get around the behaviour of multisort not sorting the referenced class-array was to make a copy of it as below:
$clsVar =& new abc();
$newData = $clsVar->data;
foreach ($newData as $key => $row)
{
$position[$key] = $key;
}
array_multisort($position, SORT_DESC, $newData);
Now newData will contain the sorted array as expected.
Hopefully this helps someone else!
[#36] [2007-04-10 03:01:43]
<?php
$strDeger = 'aaaa|bbbb|cccc';
$arrBol = explode('|',$strDeger);
array_multisort($arrBol, SORT_DESC);
for($i = 0; $i <= count($arrBol); $i++) {
echo $arrBol[$i].'<br />';
}
?>
[#37] vermon7 [2007-02-27 13:23:12]
When using array_multisort() on copies of arrays, it is changing all the copies, even if you modify the copy before using array_multisort().
I've avoided this bug by serializing a copy of array before calling array_multisort, and unserializg it after array_multisort() Look at the code:
<?php
$records_copy = serialize($records) ;
array_multisort ( $records[$sort_field] , $records[$sort2_field] ) ;
$records_copy = unserialize($records_copy) ;
?>
[#38] Jon L. -- intel352 [AT] gmail [DOT] com [2007-02-26 08:27:20]
This is my solution for a dynamic multisort, using POST values. This doesn't account for a need to sort by multiple columns at once, but could be modified for that purpose.
<?php
$sort['direction'] = $_POST['sort_direction'] ? $_POST['sort_direction'] : 'SORT_ASC';
$sort['field'] = $_POST['sort_field'] ? $_POST['sort_field'] : 'value';
$array_to_sort = array();
$array_to_sort['TestCase1'] = array('name'=>'Test1','value'=>'218');
$array_to_sort['TestCase2'] = array('name'=>'Test2','value'=>'10');
$array_to_sort['TestCase3'] = array('name'=>'Test3','value'=>'64');
$sort_arr = array();
foreach($array_to_sort AS $uniqid => $row){
foreach($row AS $key=>$value){
$sort_arr[$key][$uniqid] = $value;
}
}
print '<b>Before sorting</b>: <br> <pre>';
print_r($array_to_sort);
print '</pre>';
if($sort['direction']){
array_multisort($sort_arr[$sort['field']], constant($sort['direction']), $array_to_sort);
}
print '<b>After sorting</b>: <br> <pre>';
print_r($array_to_sort);
print '</pre>';
?>
This example prints out:
Before sorting:
Array
(
[TestCase1] => Array
(
[name] => Test1
[value] => 218
)
[TestCase2] => Array
(
[name] => Test2
[value] => 10
)
[TestCase3] => Array
(
[name] => Test3
[value] => 64
)
)
After sorting:
Array
(
[TestCase2] => Array
(
[name] => Test2
[value] => 10
)
[TestCase3] => Array
(
[name] => Test3
[value] => 64
)
[TestCase1] => Array
(
[name] => Test1
[value] => 218
)
)
[#39] [2006-12-01 06:58:21]
casting the parameter arrays for array_multisort seem to make the sorting ineffective?
for example:-
<?php
foreach((array)$report_files as $report_files_i)
{
$file_stat = stat($report_files_i);
$report_files_x[] = array(
'filename' => $report_files_i
,'basename' => basename($report_files_i)
,'ctime' => date("D, M j, Y",$file_stat['ctime'])
,'size' => $file_stat['size']
);
$basename_i[] = strtolower(basename($report_files_i)); // case insensitive
}
array_multisort($basename_i, SORT_ASC, $report_files_x);
?>
The above works but if you change the last time to :-
<?php
array_multisort((array)$basename_i, SORT_ASC, (array)$report_files_x);
?>
...adding the (array) cast doesn't sort the main array ...
[#40] brettz9 throu gh yah [2006-09-14 00:04:21]
Often, one may have a group of arrays which have parallel data that need to be kept associated with each other (e.g., the various attribute values of a group of elements might be stored in their own arrays). Using array_multisort as is, by specifying additional fields, it is possible, as in the documentation example cited below, that this association will be lost.
To take this example set of data from the documentation:
<?php
$ar1 = array("10", 100, 100, "a");
$ar2 = array(1, 3, "2", 1);
?>
The example goes on to sort it this way:
<?php
array_multisort($ar1, $ar2);
?>
In this case, although the "10" remains associated with the first '1' after being sorted, the "2" and '3' are reversed from their original order.
In order to sort by one field only (yet still have the other array(s) being correspondingly sorted), one can use array_keys (which makes an array out of the keys) to ensure that no further sub-sorting is performed. This works because array_keys is making an array for which no duplicates can exist (since keys will be unique), and thus, the subsequent fields will have no relevance as far as subsorting.
So, using the above data, we can perform this sort instead:
<?php
$ar3 = array_keys($ar1);
array_multisort($ar1, $ar3, $ar2);
?>
which, when $ar1 and $ar2 are dumped gives:
array(4) {
[0]=> string(2) "10"
[1]=> string(1) "a"
[2]=> int(100)
[3]=> int(100)
}
array(4) {
[0]=> int(1)
[1]=> int(1)
[2]=> int(3)
[3]=> string(1) "2"
}
[#41] ricardo [2006-09-04 05:47:05]
Hi,
Modded the function from KES,
goals:
- Object oriented
- string comparision using naturalordening
code:
<?php
class HtmlTable{
var $sortorder;
var $rows;
//row adding stuf and constructor removed
function sort($sortorder){
if(is_array($sortorder)){
$this->sortorder=$sortorder;
usort($this->rows,array(&$this,'sort_compare'));
}
}
function sort_compare($a,$b){//sort function
$result=0;
foreach($this->sortorder as $key=>$value){
$result=strnatcmp($a[$key],$b[$key]);
if($result==0)continue;
if($value=='desc')$result=$result*-1;
break;
}
return $result;
}
}
?>
[#42] LPChip [2006-08-28 06:04:43]
I was looking for a way to dynamically multisort my array.
By dynamically I mean that its not static what column will be sorted and if its ASC or DESC, and the ability to have more than one sorts.
This is the way a database would allow you to do.
The best way to dynamically do this, is by using eval.
The code below is partly what I used. (eg, I left out where the arrays were made and stuff, but the important part is here.)
<?php
$orderby_arr = array("col1 ASC";"col2 DESC");
// prepare multisort using eval
$eval_sort = "array_multisort(";
if ($orderby !="") {
$orderby_arr_c = count($orderby_arr);
for ($orderby_walk=0; $orderby_walk < $orderby_arr_c; $orderby_walk++) {
$pos = strpos($orderby_arr[$orderby_walk], " ");
$orderby_col = substr($orderby_arr[$orderby_walk], 0, $pos);
$orderby_type = substr($orderby_arr[$orderby_walk], $pos+1);
$eval_sort .= "\$this->OrderBy[$orderby_col]" . ", SORT_$orderby_type,";
}
}
$eval_sort .= " \$this->Current_Query);";
// if there's an array, sort it.
if ($this->Current_Query_m != -1) eval($eval_sort);
?>
[#43] RQuadling at GMail dot com [2006-08-07 05:53:23]
Extending KES's example (http://www.php.net/manual/en/function.array-multisort.php#68452) to look like array_multisort().
NOTE: Fully commented code is available at http://rquadling.php1h.com (sorry for the ads).
The syntax is the same as array_multisort().
You also have 3 additional parameters you can use:
AMC_SORT_STRING_CASELESS to sort the strings case insensitively.
AMC_LOSE_ASSOCIATION (the default behaviour) to lose the associations for the array.
AMC_KEEP_ASSOCIATION to keep the associations for the array.
Other than that, these function work together JUST like array_multisort but sorts using column(s) without the need to first extract the columns into individual arrays.
<?php
define ('AMC_SORT_STRING_CASELESS', SORT_STRING + 1);
define ('AMC_LOSE_ASSOCIATION', 1001);
define ('AMC_KEEP_ASSOCIATION', 1002);
define ('AMC_SORT_ORDER', 1003);
define ('AMC_SORT_TYPE', 1004);
function array_multisort_column(array &$a_data, $m_mixed1)
{
$a_Args = func_get_args();
$i_Args = func_num_args();
$GLOBALS['a_AMC_ordering'] = array();
$a_Columns = array_keys(reset($a_data));
$b_KeepAssociation = False;
for($i_Arg = 1 ; $i_Arg < $i_Args ; )
{
if (in_array($a_Args[$i_Arg], $a_Columns))
{
$s_Column = $a_Args[$i_Arg];
$GLOBALS['a_AMC_ordering'][$a_Args[$i_Arg]] = array
(
AMC_SORT_ORDER => SORT_ASC,
AMC_SORT_TYPE => SORT_REGULAR,
);
while
(
isset($a_Args[$i_Arg + 1]) &&
in_array
(
$a_Args[$i_Arg + 1],
array
(
AMC_KEEP_ASSOCIATION,
AMC_LOSE_ASSOCIATION,
AMC_SORT_STRING_CASELESS,
SORT_ASC,
SORT_DESC
SORT_NUMERIC,
SORT_REGULAR,
SORT_STRING,
),
True
)
)
{
if (in_array($a_Args[$i_Arg + 1], array(SORT_ASC, SORT_DESC), True))
{
$GLOBALS['a_AMC_ordering'][$s_Column][AMC_SORT_ORDER] = $a_Args[$i_Arg + 1];
}
elseif (in_array($a_Args[$i_Arg + 1], array(SORT_REGULAR, SORT_NUMERIC, SORT_STRING, AMC_SORT_STRING_CASELESS), True))
{
$GLOBALS['a_AMC_ordering'][$s_Column][AMC_SORT_TYPE] = $a_Args[$i_Arg + 1];
}
elseif (AMC_KEEP_ASSOCIATION == $a_Args[$i_Arg + 1])
{
$b_KeepAssociation = True;
}
++$i_Arg;
}
}
++$i_Arg;
}
$s_Sorter = ($b_KeepAssociation ? 'uasort' : 'usort');
$b_Result = $s_Sorter($a_data, 'array_multisort_column_cmp');
unset($GLOBALS['a_AMC_ordering']);
return $b_Result;
}
function array_multisort_column_cmp(array &$a_left, array &$a_right)
{
$i_Result = 0;
foreach($GLOBALS['a_AMC_ordering'] as $s_Column => $a_ColumnData)
{
switch ($a_ColumnData[AMC_SORT_TYPE])
{
case SORT_NUMERIC :
$i_ColumnCompareResult =
((intval($a_left[$s_Column]) == intval($a_right[$s_Column]))
?
0
:
((intval($a_left[$s_Column]) < intval($a_right[$s_Column]))
?
-1
:
1
)
);
break;
case SORT_STRING :
$i_ColumnCompareResult = strcmp((string)$a_left[$s_Column], (string)$a_right[$s_Column]);
break;
case AMC_SORT_STRING_CASELESS :
$i_ColumnCompareResult = strcasecmp((string)$a_left[$s_Column], (string)$a_right[$s_Column]);
break;
case SORT_REGULAR :
default :
$i_ColumnCompareResult =
(($a_left[$s_Column] == $a_right[$s_Column])
?
0
:
(($a_left[$s_Column] < $a_right[$s_Column])
?
-1
:
1
)
);
break;
}
if (0 == $i_ColumnCompareResult)
{
continue;
}
$i_Result = $i_ColumnCompareResult * (($a_ColumnData[AMC_SORT_ORDER] == SORT_DESC) ? -1 : 1);
break;
}
return $i_Result;
}
?>
[#44] KES http://kes.net.ua [2006-07-27 05:30:13]
<?php
//sort by second column then first one
$orderBy=array('0'=>'desc', 'first'=>'asc');
function KES_cmp($a, $b) {
global $orderBy;
$result= 0;
foreach( $orderBy as $key => $value ) {
if( $a[$key] == $b[$key] ) continue;
$result= ($a[$key] < $b[$key])? -1 : 1;
if( $value=='desc' ) $result= -$result;
break;
}
return $result;
}
$result= array();
$result[]= array( 'first'=>6, 2);
$result[]= array( 'first'=>3, 2);
$result[]= array( 'first'=>1, 3);
$result[]= array( 'first'=>1, 2);
$result[]= array( 'first'=>6, 1);
print "<b>Source</b>";
print_r($result);
usort($result, 'KES_cmp');
print "<b>Result</b>";
print_r($result);
?>
[#45] KES [2006-07-27 04:35:21]
It is very handy to have function, which sort like this:
$arrayToSort[]= array(0 => ".", "type" => "dir");
$arrayToSort[]= array(0 => "qf", "type" => "file");
$arrayToSort[]= array(0 => "..", "type" => "dir");
$arrayToSort[]= array(0 => "text.txt", "type" => "file");
$arrayToSort[]= array(0 => "hello", "type" => "dir");
//first sort by the column 'type', then sort by the column '0'
$howToSort= array('type'=> 'asc', 0=> 'desc');
multisort($arrayToSort, $howToSort);
The result:
0 | type
----------------------------
. | dir
.. | dir
hello | dir
text.txt | file
qf | file
[#46] scott - evolove - net - work it out [2006-03-22 19:51:22]
A very simple way to sort an array of associative arrays by some value is to use usort.
I needed to sort an array of 20 data structures by their 'distance' value:
Array
(
[0] => Array
(
[blahblah] => blahblah
[distance] => 6
)
[1] => Array
(
you get the idea....
Here's the code:
--------------------
usort($results, "distributor_compare");
function distributor_compare($a, $b) {
$adist = intval($a['distance']);
$bdist = intval($b['distance']);
if ($adist == $bdist) {
return 0;
}
return ($adist < $bdist) ? -1 : 1;
}
--------------------
[#47] peter dot graham at tcat dot ac dot uk [2006-02-16 07:16:04]
[#48] mail at theopensource dot com [2006-01-31 11:34:23]
I wanted to share with you a function that I created to make the array_multisort process much easier for myself... There was some interesting things that I encountered and I will post that in the comments.
I created this function so that all I have to do is tell it what column I want to sort through in a one level deep multidimensional array. You can Try this code in your browser to view the results
ex/
<?php
//Here is an array example
$test[0]['name'] = "David";
$test[0]['age'] = 28;
$test[1]['name'] = "Dennis";
$test[1]['age'] = 23;
$test[2]['name'] = "Joseph";
$test[2]['age'] = 42;
//Here is the Function
function sortmddata($array, $by, $order, $type){
//$array: the array you want to sort
//$by: the associative array name that is one level deep
////example: name
//$order: ASC or DESC
//$type: num or str
$sortby = "sort$by"; //This sets up what you are sorting by
$firstval = current($array); //Pulls over the first array
$vals = array_keys($firstval); //Grabs the associate Arrays
foreach ($vals as $init){
$keyname = "sort$init";
$$keyname = array();
}
//This was strange because I had problems adding
//Multiple arrays into a variable variable
//I got it to work by initializing the variable variables as arrays
//Before I went any further
foreach ($array as $key => $row) {
foreach ($vals as $names){
$keyname = "sort$names";
$test = array();
$test[$key] = $row[$names];
$$keyname = array_merge($$keyname,$test);
}
}
//This will create dynamic mini arrays so that I can perform
//the array multisort with no problem
//Notice the temp array... I had to do that because I
//cannot assign additional array elements to a
//varaiable variable
if ($order == "DESC"){
if ($type == "num"){
array_multisort($$sortby,SORT_DESC, SORT_NUMERIC,$array);
} else {
array_multisort($$sortby,SORT_DESC, SORT_STRING,$array);
}
} else {
if ($type == "num"){
array_multisort($$sortby,SORT_ASC, SORT_NUMERIC,$array);
} else {
array_multisort($$sortby,SORT_ASC, SORT_STRING,$array);
}
}
//This just goed through and asks the additional arguments
//What they are doing and are doing variations of
//the multisort
return $array;
}
//Now to test it
$test = sortmddata($test,'age','ASC','num');
print_r ($test);
//This will return
//Array (
//[0] => Array ([name] => Dennis [age] => 23 )
//[1] => Array ( [name] => David [age] => 28 )
//[2] => Array ( [name] => Joseph [age] => 42 )
//)
?>
There you go... please let me know what you think if you like.
[#49] php a-t-the-r-a-t-e chir.ag [2006-01-05 14:10:58]
Re: phu at kungphu, 19-Dec-2005 11:36
asort($test) will not let me specify which columns to sort ASC/DESC, NUMERIC/STRING etc.
I have data similar to what you specified. Now I want to sort $test by points DESC and name ASC. Here's my function that does it, based on suggestions on this page. It uses array_multisort (and hence acts just like it: preserving string-keys etc.)
<?php
function arrayColumnSort()
{
$n = func_num_args();
$ar = func_get_arg($n-1);
if(!is_array($ar))
return false;
for($i = 0; $i < $n-1; $i++)
$col[$i] = func_get_arg($i);
foreach($ar as $key => $val)
foreach($col as $kkey => $vval)
if(is_string($vval))
${"subar$kkey"}[$key] = $val[$vval];
$arv = array();
foreach($col as $key => $val)
$arv[] = (is_string($val) ? ${"subar$key"} : $val);
$arv[] = $ar;
call_user_func_array("array_multisort", $arv);
return $ar;
}
$test["pete"]['points']=1;
$test["pete"]['name']='Peter';
$test["mike"]['points']=5;
$test["mike"]['name']='Mike';
$test["zoo"]['points']=2;
$test["zoo"]['name']='John Zoo';
$test["ab"]['points']=2;
$test["ab"]['name']='John Ab';
$test1 = $test;
asort($test1);
$test2 = arrayColumnSort("points", SORT_DESC, SORT_NUMERIC, "name", SORT_ASC, SORT_STRING, $test);
print_r($test1); // asort
print_r($test2); // arrayColumnSort
?>
Output from asort:
Array
(
[pete] => Array
(
[points] => 1
[name] => Peter
)
[ab] => Array
(
[points] => 2
[name] => John Ab
)
[zoo] => Array
(
[points] => 2
[name] => John Zoo
)
[mike] => Array
(
[points] => 5
[name] => Mike
)
)
Output from arrayColumnSort:
Array
(
[mike] => Array
(
[points] => 5
[name] => Mike
)
[ab] => Array
(
[points] => 2
[name] => John Ab
)
[zoo] => Array
(
[points] => 2
[name] => John Zoo
)
[pete] => Array
(
[points] => 1
[name] => Peter
)
)
[#50] phu at kungphu [2005-12-19 11:36:32]
Notepad's example using asort/arsort will -not- work unless 'points' is defined -before- 'name'.
Running the posted code sorts by 'name', which was not the point of the previous posts. Defining 'points' as 'apoints' also did not work; however, defining 'points' first yields correct sorting:
$test[0]['points']=1;
$test[0]['name']='Peter';
$test[1]['points']=5;
$test[1]['name']='Mike';
$test[2]['points']=2;
$test[2]['name']='John';
asort($test);
It appears asort uses the first defined element to sort a multidimensional array.
[#51] notepad at codewalkers dot com [2005-12-09 16:33:22]
for you guys trying to sort scores on an associative multi-dimensional array, why are you creating your own functions?
<?php
$test[0]['name']='Peter';
$test[0]['points']=1;
$test[1]['name']='Mike';
$test[1]['points']=5;
$test[2]['name']='John';
$test[2]['points']=2;
asort($test);
// or even arsort();
?>
the above seems to work for me...
[#52] Shmee [2005-09-30 06:46:25]
[#53] RWC [2005-09-25 13:45:53]
This is the simpler version of the function by AlberT.
A lot of times you have got an array like this:
$test[0]['name']='Peter';
$test[0]['points']=1;
$test[1]['name']='Mike';
$test[1]['points']=5;
$test[2]['name']='John';
$test[2]['points']=2;
You just want to sort on the index in the second dimension, ie. on points in the above example.
You can use the function below and call it like this:
$test = multi_sort($test, $key = 'points');
function multi_sort($array, $akey)
{
function compare($a, $b)
{
global $key;
return strcmp($a[$key], $b[$key]);
}
usort($array, "compare");
return $array;
}
Note: to be able to use $key in the compare function, it can not simply be passed as a parameter. It has to be declared global and set somewhere outside of compare().
[#54] AlberT at SuperAlberT dot it [2005-07-18 06:59:39]
a nice piece of code to do an "array_key_multi_sort()" is the following:
<?php
function array_key_multi_sort(&$arr, $l , $f='strnatcasecmp') {
return usort($arr, create_function('$a, $b', "return $f(\$a['$l'], \$b['$l']);"));
}
?>
[#55] kencomer at kencomer dot com [2005-06-12 23:48:39]
If your data is in an associative array that you would need to separate into columns such as those retrieved with your favorite flavor of _fetch_array() in order to be able to use multisort(), you should consider using uasort() or usort() as an alternative. Here is an example of how this could be beneficial:
(key is employee number which remains intact; rows are sorted by surname, firstname)
<?php
function namecmp( $row1,$row2 )
{
$first = strcmp($row1['surname'], $row2['surname']) ;
if ( $first )
return $first ;
else
return strcmp($row1['name'], $row2['name']) ;
}
$test = array( '11122202' => array('empno'=>11122202,'name'=>'geezer'
,'surname'=>'schmidt','age'=>96,'sex'=>'male')
,'11122204' => array('empno'=>11122204,'name'=>'coed'
,'surname'=>'beaujolais','age'=>18,'sex'=>'female')
,'11122206' => array('empno'=>11122206,'name'=>'immortal'
,'surname'=>'ramos','age'=>21,'sex'=>'male')
,'11122208' => array('empno'=>11122208,'name'=>'babyface'
,'surname'=>'brown','age'=>1,'sex'=>'male')
,'11122210' => array('empno'=>11122210,'name'=>'exjock'
,'surname'=>'gatti','age'=>48,'sex'=>'male')
,'11122212' => array('empno'=>11122212,'name'=>'jailbait'
,'surname'=>'muhammed','age'=>15,'sex'=>'female') )
;
echo "<pre>" ;
print_r( $test ) ;
uasort($test,'namecmp') ;
echo "----sorting----<br \>";
print_r( $test ) ;
echo "</pre>" ;
?>
Array
(
[11122202] => Array
(
[empno] => 11122202
[name] => geezer
[surname] => schmidt
[age] => 96
[sex] => male
)
[11122204] => Array
(
[empno] => 11122204
[name] => coed
[surname] => beaujolais
[age] => 18
[sex] => female
)
[11122206] => Array
(
[empno] => 11122206
[name] => immortal
[surname] => ramos
[age] => 21
[sex] => male
)
[11122208] => Array
(
[empno] => 11122208
[name] => babyface
[surname] => brown
[age] => 1
[sex] => male
)
[11122210] => Array
(
[empno] => 11122210
[name] => exjock
[surname] => gatti
[age] => 48
[sex] => male
)
[11122212] => Array
(
[empno] => 11122212
[name] => jailbait
[surname] => muhammed
[age] => 15
[sex] => female
)
)
----sorting----
Array
(
[11122204] => Array
(
[empno] => 11122204
[name] => coed
[surname] => beaujolais
[age] => 18
[sex] => female
)
[11122208] => Array
(
[empno] => 11122208
[name] => babyface
[surname] => brown
[age] => 1
[sex] => male
)
[11122210] => Array
(
[empno] => 11122210
[name] => exjock
[surname] => gatti
[age] => 48
[sex] => male
)
[11122212] => Array
(
[empno] => 11122212
[name] => jailbait
[surname] => muhammed
[age] => 15
[sex] => female
)
[11122206] => Array
(
[empno] => 11122206
[name] => immortal
[surname] => ramos
[age] => 21
[sex] => male
)
[11122202] => Array
(
[empno] => 11122202
[name] => geezer
[surname] => schmidt
[age] => 96
[sex] => male
)
)
[#56] stevec at NO-/ dot /-SPAM dot qiguang dot net [2005-04-13 08:19:02]
Be careful when using array_multisort() on copies of arrays, as you might end up changing the original array. Given the following code:
<?php
$test1 = array(4,3,2,1);
$test2 = $test1;
$test3 = array('a', 'b', 'c', 'd');
array_multisort($test2, SORT_ASC, $test3);
echo 'test1:';
print_r($test1);
echo 'test2:';
print_r($test2);
echo 'test3:';
print_r($test3);
?>
You would expect:
test1:Array
(
[0] => 4
[1] => 3
[2] => 2
[3] => 1
)
test2:Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
test3:Array
(
[0] => d
[1] => c
[2] => b
[3] => a
)
However, if you run the code, you actually get:
test1:Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
test2:Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
test3:Array
(
[0] => d
[1] => c
[2] => b
[3] => a
)
Note that the original ($test1) ends up being sorted even though it was never called by array_multisort(). To work around this, insert a statement to modify the copy ($test2) before calling array_multisort() on it. The following code will produce the expected "correct" results:
<?php
$test1 = array(4,3,2,1);
$test2 = $test1;
$test3 = array('a', 'b', 'c', 'd');
$test2[0] = $test2[0]; // fix
array_multisort($test2, SORT_ASC, $test3);
echo 'test1:';
print_r($test1);
echo 'test2:';
print_r($test2);
echo 'test3:';
print_r($test3);
?>
This seems to be a resurrection of the closed bug #8130. Also, someone reported this behavior in bug #32031, but it was incorrectly labeled "bogus" in reference to bug #25359, which is a different issue.
[#57] joao at intrasystems dot com dot br [2005-04-07 12:27:57]
Exemple of sorting multi-dimensional arrays by one of it's fields:
$result[0]['nome']='Joao';
$result[0]['order']=5;
$result[1]['nome']='Pedro';
$result[1]['order']=1;
$result[2]['nome']='Marcelo';
$result[2]['order']=3;
foreach($result as $res)
$sortAux[] = $res['order'];
array_multisort($sortAux, SORT_ASC, $result);
print_r($result);
produces:
Array
(
[0] => Array
(
[nome] => Pedro
[order] => 1
)
[1] => Array
(
[nome] => Marcelo
[order] => 3
)
[2] => Array
(
[nome] => Joao
[order] => 5
)
)
[#58] Toni [2004-11-10 03:30:06]
An example to sort an array by 3 criteria:
$recordset is an array of results from a query to a database, that I sort using $matrix as auxiliary array. First numeric, Second and Third alphabetically.
<?php
for($idx=0;$idx<$toShow;$idx++){
$matrix[0][$id]=$recordset[$id][0];
$matrix[1][$id]=$recordset[$id][1];
$matrix[2][$id]=$recordset[$id][10];
}
array_multisort($matrix[0], SORT_DESC, SORT_NUMERIC,$matrix[1], SORT_STRING, SORT_ASC,$matrix[2], SORT_STRING, SORT_ASC);
?>
[#59] meddle at dzygn.com [2004-10-05 07:40:09]
If you want to sort a multidomensional array by key name you cannot use array_multisort. ie: for an array named $archivos that prints like this:
Array
(
[0] => Array
(
[index] => 0
[name] => test
)
[1] => Array
(
[index] => 0
[name] => watertaxi.jpg
)
[2] => Array
(
[index] => 0
[name] => 2_0003.JPG
)
[3] => Array
(
[index] => 0
[name] => 24A_0025.JPG
)
[4] => Array
(
[index] => 1
[name] => _CIMG3501.JPG
)
)
If I wanted to order by "name" I'd use:
function comparar($a, $b) {
return strnatcasecmp($a["name"], $b["name"]);
}
usort($archivos, "comparar");
This function performs a case insensitive string comparison using a "natural order" algorithm (strnatcasecmp), resulting in:
Array
(
[0] => Array
(
[index] => 0
[name] => 2_0003.JPG
)
[1] => Array
(
[index] => 0
[name] => 24A_0025.JPG
)
[2] => Array
(
[index] => 0
[name] => test
)
[3] => Array
(
[index] => 0
[name] => watertaxi.jpg
)
[4] => Array
(
[index] => 1
[name] => _CIMG3501.JPG
)
)
[#60] kat dot n0spam at audiogalaxy dot com [2001-08-23 22:25:22]
If you're having problems with array_multisort changing variables in global space when it is called inside a function and you're not passing in the function parameters by reference you can alleviate the problem by calling array_multisort with its parameters by reference.
array_multisort(&$a, SORT_DESC, &$b);
More details here in my bug report:
http://www.php.net/bugs.php?id=12936