How to sort an array of associative arrays by value of a given key in PHP?
给定此数组:
1 2 3 4 5 6 7 |
我想按价格对
1 2 3 4 5 6 7 |
我该怎么做?
你说得对,你要找的功能是
下面是一个直接从手册中选取的示例,并根据您的情况进行了调整:
1 2 3 4 5 6 | $price = array(); foreach ($inventory as $key => $row) { $price[$key] = $row['price']; } array_multisort($price, SORT_DESC, $inventory); |
0
1 2 3 |
PHP 7 +
从php 7开始,可以使用
您可以这样进行升序排序:
1 2 3 |
或者像这样的降序排序:
1 2 3 |
要了解这是如何工作的,请注意,
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
还要注意的是,宇宙飞船操作员
returns 0 if both operands are equal, 1 if the left is greater, and -1 if the right is greater
这正是
makes writing ordering callbacks for use with
usort() easier
PHP 5.3 +
php 5.3引入了匿名函数,但还没有spaceship操作符。我们仍然可以使用
1 2 3 4 | usort($inventory, function ($item1, $item2) { if ($item1['price'] == $item2['price']) return 0; return $item1['price'] < $item2['price'] ? -1 : 1; }); |
请注意,尽管处理整数值的比较器只返回值的差异是很常见的,比如
Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.
在php 5.x中使用
虽然其他人正确地建议使用
1 |
因为数组元素本身就是带有字符串键的数组,所以最好定义一个自定义比较函数。这是非常快速和容易做到的。试试这个:
1 2 3 4 5 6 7 |
生成以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
我就这样结束了:
1 2 3 4 5 6 7 8 9 10 | function sort_array_of_array(&$array, $subfield) { $sortarray = array(); foreach ($array as $key => $row) { $sortarray[$key] = $row[$subfield]; } array_multisort($sortarray, SORT_ASC, $array); } |
只需调用函数,传递数组和第二级数组的字段名。像:
1 | sort_array_of_array($inventory, 'price'); |
您可以使用带匿名功能的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | $inventory = array(array("type"=>"fruit","price"=>3.50), array("type"=>"milk","price"=>2.90), array("type"=>"pork","price"=>5.43), ); function pricesort($a, $b) { $a = $a['price']; $b = $b['price']; if ($a == $b) return 0; return ($a > $b) ? -1 : 1; } usort($inventory,"pricesort"); // uksort($inventory,"pricesort"); print("first:".$inventory[0]['type']." "); // for usort(): prints milk (item with lowest price) // for uksort(): prints fruit (item with key 0 in the original $inventory) // foreach prints the same for usort and uksort. foreach($inventory as $i){ print($i['type'].":".$i['price']." "); } |
输出:
2根据php中给定键的值对关联数组进行排序:
uasort(http://php.net/uasort)允许您根据自己定义的函数对数组进行排序。在您的例子中,这很简单:
1 2 3 4 5 6 7 8 9 10 11 |
在10万份记录中进行了测试:以秒为单位的时间(由funciton microtime计算)。仅用于排序关键位置时的唯一值。
@josh davis的功能解决方案:花费时间:1.5768740177155
矿山解决方案:花费时间:0.094044923782349
解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 | function SortByKeyValue($data, $sortKey, $sort_flags=SORT_ASC) { if (empty($data) or empty($sortKey)) return $data; $ordered = array(); foreach ($data as $key => $value) $ordered[$value[$sortKey]] = $value; ksort($ordered, $sort_flags); return array_values($ordered); *// array_values() added for identical result with multisort* } |
此功能可重复使用:
1 2 3 4 5 | function usortarr(&$array, $key, $callback = 'strnatcasecmp') { uasort($array, function($a, $b) use($key, $callback) { return call_user_func($callback, $a[$key], $b[$key]); }); } |
默认情况下,它在字符串值上工作得很好,但是如果您的所有值都是数字,则必须为数字比较函数的回调子函数。
您可以尝试定义自己的比较函数,然后使用usort。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | //Just in one line custom function function cmp($a, $b) { return (float) $a['price'] < (float)$b['price']; } @uasort($inventory,"cmp"); print_r($inventory); //result Array ( [2] => Array ( [type] => pork [price] => 5.43 ) [0] => Array ( [type] => fruit [price] => 3.5 ) [1] => Array ( [type] => milk [price] => 2.9 ) ) |
这是我很久以前发现的一种清理方法。这非常有效,并且可以快速更改以接受对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /** * A method for sorting arrays by a certain key:value. * SortByKey is the key you wish to sort by * Direction can be ASC or DESC. * * @param $array * @param $sortByKey * @param $sortDirection * @return array */ private function sortArray($array, $sortByKey, $sortDirection) { $sortArray = array(); $tempArray = array(); foreach ( $array as $key => $value ) { $tempArray[] = strtolower( $value[ $sortByKey ] ); } if($sortDirection=='ASC'){ asort($tempArray ); } else{ arsort($tempArray ); } foreach ( $tempArray as $key => $temp ){ $sortArray[] = $array[ $key ]; } return $sortArray; } |
要更改排序对象的方法,只需更改以下行:
要运行该方法,只需执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | $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') ); $result1 = array_msort($arr1, array('name'=>SORT_DESC); $result2 = array_msort($arr1, array('cat'=>SORT_ASC); $result3 = array_msort($arr1, array('name'=>SORT_DESC, 'cat'=>SORT_ASC)); 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; } |
完全动态功能我跳到这里进行关联数组排序,在http://php.net/manual/en/function.sort.php上发现了这个惊人的函数。这个函数是非常动态的,用指定的键按升序和降序排序。
简单函数按特定键对数组进行排序。维护索引关联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <?php function array_sort($array, $on, $order=SORT_ASC) { $new_array = array(); $sortable_array = array(); if (count($array) > 0) { foreach ($array as $k => $v) { if (is_array($v)) { foreach ($v as $k2 => $v2) { if ($k2 == $on) { $sortable_array[$k] = $v2; } } } else { $sortable_array[$k] = $v; } } switch ($order) { case SORT_ASC: asort($sortable_array); break; case SORT_DESC: arsort($sortable_array); break; } foreach ($sortable_array as $k => $v) { $new_array[$k] = $array[$k]; } } return $new_array; } $people = array( 12345 => array( 'id' => 12345, 'first_name' => 'Joe', 'surname' => 'Bloggs', 'age' => 23, 'sex' => 'm' ), 12346 => array( 'id' => 12346, 'first_name' => 'Adam', 'surname' => 'Smith', 'age' => 18, 'sex' => 'm' ), 12347 => array( 'id' => 12347, 'first_name' => 'Amy', 'surname' => 'Jones', 'age' => 21, 'sex' => 'f' ) ); print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php $inventory = array( array("type"=>"fruit","price"=>3.50), array("type"=>"milk","price"=>2.90), array("type"=>"pork","price"=>5.43), ); function myfunc($a,$b){ return strnatcmp($a['price'],$b['price']); } $result=usort ($inventory,"myfunc");?> [cc lang="php"]<?php print_r(array_reverse($inventory)); ?> |
< /代码>
简单的解决方案:)
输出是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
试试这个:
1 |
参考如下:http://php.net/manual/en/function.asort.php
请在此处查看各种排序标志:http://www.php.net/manual/en/function.sort.php