array_multisort() - 对多个数组或多维数组进行排序 - php 数组函数
array_multisort()
(PHP 4, PHP 5, PHP 7)
对多个数组或多维数组进行排序
说明
array_multisort(array &$array1[,mixed $array1_sort_order= SORT_ASC[,mixed $array1_sort_flags= SORT_REGULAR[,mixed $...]]]): boolarray_multisort()可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序。
关联(string)键名保持不变,但数字键名会被重新索引。
Note:If two members compare as equal, their relative order in the sorted array is undefined.
参数
$array1要排序的array。
$array1_sort_order之前array参数要排列的顺序。SORT_ASC
按照上升顺序排序,SORT_DESC
按照下降顺序排序。
此参数可以和$array1_sort_flags互换,也可以完全删除,默认是SORT_ASC
。
为array参数设定选项:
排序类型标志:
SORT_REGULAR
-将项目按照通常方法比较(不修改类型)SORT_NUMERIC
-按照数字大小比较SORT_STRING
-按照字符串比较SORT_LOCALE_STRING
-根据当前的本地化设置,按照字符串比较。它会使用 locale 信息,可以通过setlocale()修改此信息。SORT_NATURAL
-以字符串的"自然排序",类似natsort()SORT_FLAG_CASE
-可以组合(按位或 OR)SORT_STRING
或者SORT_NATURAL
大小写不敏感的方式排序字符串。
参数可以和$array1_sort_order交换或者省略,默认情况下是SORT_REGULAR
。
可选的选项,可提供更多数组,跟随在 sort order 和 sort flag 之后。提供的数组和之前的数组要有相同数量的元素。换言之,排序是按字典顺序排列的。
返回值
成功时返回TRUE
,或者在失败时返回FALSE
。
更新日志
版本 | 说明 |
---|---|
5.4.0 | $array1_sort_flags增加SORT_NATURAL 和SORT_FLAG_CASE 选项。 |
5.3.0 | $array1_sort_flags增加选项SORT_LOCALE_STRING 。 |
范例
多个数组排序
这个例子里,排序后,第一个数组会包含 0、 10、 100、 100。第二个数组会包含 4、1、 2、 3。第二个数组里的项目对应第一个数组后也进行了排序(100 和 100)。
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) }
排序多维数组
本例中在排序后,第一个数组将变成"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) } }
对数据库结果进行排序
本例中data数组中的每个单元表示一个表中的一行。这是典型的数据库记录的数据集合。
例子中的数据如下:
volume | edition -------+-------- 67 | 2 86 | 1 85 | 6 98 | 2 86 | 6 67 | 7
数据全都存放在名为data的数组中。这通常是通过循环从数据库取得的结果,例如mysql_fetch_assoc()。
本例中将把volume降序排列,把edition升序排列。
现在有了包含有行的数组,但是array_multisort()需要一个包含列的数组,因此用以下代码来取得列,然后排序。
数据集合现在排好序了,结果如下:
volume | edition -------+-------- 98 | 2 86 | 1 86 | 6 85 | 6 67 | 2 67 | 7
不区分大小写字母排序
SORT_STRING
和SORT_REGULAR
都是区分大小写字母的,大写字母会排在小写字母之前。
要进行不区分大小写的排序,就要按照原数组的小写字母拷贝来排序。
以上例程会输出:
Array ( [0] => Alpha [1] => atomic [2] => bank [3] => Beta )
参见
usort()
使用用户自定义的比较函数对数组中的值进行排序- 数组排序函数对比
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(). The sorted array is now in the return value of the function instead of being passed by reference.
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:
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 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);
One-liner function to sort multidimensionnal array by key, thank's to array_column
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: 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!
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().
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: 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" ), }
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.
Easiest way I find out to sort an entire multidimensional array by one element of it: ^-^
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: The example goes on to sort it this way: 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: 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" }
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"); /** * usort callback */ function distributor_compare($a, $b) { $adist = intval($a['distance']); $bdist = intval($b['distance']); if ($adist == $bdist) { return 0; } return ($adistSuper 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.if you want to sort an array by columns, this is the function to do it.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: 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: 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: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. 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 ) )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: 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.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.
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!