如何通过PHP中的给定键的值来对关联数组的数组进行sorting?

给定这个数组:

$inventory = array( array("type"=>"fruit", "price"=>3.50), array("type"=>"milk", "price"=>2.90), array("type"=>"pork", "price"=>5.43), ); 

我想按价格对$inventory的元素进行sorting得到:

 $inventory = array( array("type"=>"pork", "price"=>5.43), array("type"=>"fruit", "price"=>3.50), array("type"=>"milk", "price"=>2.90), ); 

我该怎么做?

你是对的,你正在寻找的函数是array_multisort()

下面是从手册中直接获取的一个例子,并根据您的情况进行调整:

 $price = array(); foreach ($inventory as $key => $row) { $price[$key] = $row['price']; } array_multisort($price, SORT_DESC, $inventory); 

PHP 7+

从PHP 7开始,可以使用usort简明地完成这个任务,使用太空船操作员比较元素的匿名函数 。

你可以像这样按升序sorting:

 usort($inventory, function ($item1, $item2) { return $item1['price'] <=> $item2['price']; }); 

或者像这样降序sorting:

 usort($inventory, function ($item1, $item2) { return $item2['price'] <=> $item1['price']; }); 

要理解这是如何工作的,请注意, usort采用用户提供的比较函数,其行为必须如下(来自文档):

如果第一个参数分别小于,等于或大于第二个参数,则比较函数必须返回小于,等于或大于零的整数。

还要注意, <=> ,太空船的操作员,

如果两个操作数相等,则返回0;如果左边较大,则返回1;如果右边较大,则返回-1

这正是usort需要的。 事实上,在https://wiki.php.net/rfc/combined-comparison-operator中添加;<=>到语言的几乎所有的理由是它

使书面订购callback用于usort()更容易


PHP 5.3+

PHP 5.3引入了匿名函数,但是还没有太空船运营商。 我们仍然可以使用usort来sorting我们的数组,但是它有点冗长和难以理解:

 usort($inventory, function ($item1, $item2) { if ($item1['price'] == $item2['price']) return 0; return $item1['price'] < $item2['price'] ? -1 : 1; }); 

请注意,虽然处理整数值的比较器只是返回值的差异,例如$item2['price'] - $item1['price'] ,但在这种情况下我们不能安全地做到这一点。 这是因为价格是问题提供者例子中的浮点数,但是我们传递给usort的比较函数必须返回整数才能正常工作:

从比较函数返回非整数值(如float)将导致内部转换为callback的返回值的整数。 所以0.99和0.1这样的值都会被转换为0的整数值,这将比较这些值是相等的。

在PHP 5.x中使用usort时,这是一个重要的陷阱! 我的这个答案的原始版本犯了这个错误,但我累积成千上万的意见显然没有人注意到严重的错误10 upvotes。 像我这样的缺乏智能可以使得比较函数变得简单, 正是在PHP 7中将易于使用的飞船运算符添加到语言中的原因。

由于您的数组元素是使用string键的数组本身,所以最好的办法是定义一个自定义的比较函数。 这是相当快速和容易做到的。 尝试这个:

 function invenDescSort($item1,$item2) { if ($item1['price'] == $item2['price']) return 0; return ($item1['price'] < $item2['price']) ? 1 : -1; } usort($inventory,'invenDescSort'); print_r($inventory); 

产生以下内容:

 Array ( [0] => Array ( [type] => pork [price] => 5.43 ) [1] => Array ( [type] => fruit [price] => 3.5 ) [2] => Array ( [type] => milk [price] => 2.9 ) ) 

我结束了这个:

 function sort_array_of_array(&$array, $subfield) { $sortarray = array(); foreach ($array as $key => $row) { $sortarray[$key] = $row[$subfield]; } array_multisort($sortarray, SORT_ASC, $array); } 

只要调用该函数,传递数组和二级数组的字段的名称。 喜欢:

 sort_array_of_array($inventory, 'price'); 

你可以使用匿名函数,例如

 usort($inventory, function ($a, $b) { return strnatcmp($a['price'], $b['price']); }); 

而其他人正确地build议使用array_multisort() ,出于某种原因,似乎没有答案似乎承认array_column()的存在,这可以大大简化解决scheme。 所以我的build议是:

 array_multisort(array_column($inventory, 'price'), SORT_DESC, $inventory); 
 $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']."\n\n"); // 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']."\n"); } 

输出:

 first: pork pork: 5.43 fruit: 3.5 milk: 2.9 

在100 000条logging上进行了testing:以秒为单位的时间(通过函数microtime计算)。 仅用于sorting关键位置的唯一值。

@Josh Davisfunction解决scheme: 暂停时间 :1.5768740177155

排雷解决scheme: 暂停时间 :0.094044923782349

解:

 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* } 

您可能会尝试定义您自己的比较函数,然后使用usort 。

 //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 ) ) 

该function可重复使用:

 function usortarr(&$array, $key, $callback = 'strnatcasecmp') { uasort($array, function($a, $b) use($key, $callback) { return call_user_func($callback, $a[$key], $b[$key]); }); } 

它在默认情况下可以很好地处理string值,但是如果所有的值都是数字,则必须将callback函数作为数字比较函数 。

完整的dynamic函数我跳过这里进行关联数组sorting,并在http://php.net/manual/en/function.sort.php上find了这个惊人的function。; 这个函数是非常dynamic的,按照指定的键升序和降序sorting。

简单的函数按特定键sorting数组。 保持索引关联

 <?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 

尝试这个:

 asort($array_to_sort, SORT_NUMERIC); 

参考见: http : //php.net/manual/en/function.asort.php

在这里看到各种sorting标志: http : //www.php.net/manual/en/function.sort.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') ); $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; } 
  <?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");?> <pre><?php print_r(array_reverse($inventory)); ?></pre> 

简单的解决scheme:)

输出是,

 Array ( [0] => Array ( [type] => pork [price] => 5.43 ) [1] => Array ( [type] => fruit [price] => 3.5 ) [2] => Array ( [type] => milk [price] => 2.9 ) ) 

在PHP中给定的键的值sorting关联数组的数组

 $array = array('0'=>array('price'=>'1000.50','product'=>'test1'), '1'=>array('price'=>'8800.50','product'=>'test2'), '2'=>array('price'=>'200.0','product'=>'test3')); function cmp($a, $b) { $p1 = $a['price']; $p2 = $b['price']; return (float)$p1 > (float)$p2; } @uasort($array, "cmp");