假设我有一个模仿数据库表的数组。每个数组元素代表一行,每行内是另一个包含字段名称和值的数组。
Array
(
[0] => Array
(
[name] => 'Sony TV'
[price] => 600.00
)
[1] => Array
(
[name] => 'LG TV'
[price] => 350.00
)
[2] => Array
(
[name] => 'Samsung TV'
[price] => 425.00
)
}
我想要做的是按价格对行(外部数组元素)进行排序。以下是我想要实现的目标的示例:
Array
(
[0] => Array
(
[name] => 'LG TV'
[price] => 350.00
)
[1] => Array
(
[name] => 'Samsung TV'
[price] => 425.00
)
[2] => Array
(
[name] => 'Sony TV'
[price] => 600.00
)
}
如您所见,我不需要保留外部数组的键。
这只是一个内衬
array_multisort( array_column($yourArray, "price"), SORT_ASC, $yourArray );
您也可以在这里找到它:http://php.net/manual/en/function.array-multisort.php
在该手册页上搜索“array_column”。
您需要使用usort,这是一个通过用户定义的函数对数组进行排序的函数。比如:
function cmp($a, $b)
{
if ($a["price"] == $b["price"]) {
return 0;
}
return ($a["price"] < $b["price"]) ? -1 : 1;
}
usort($yourArray,"cmp")
usort()
:
function sort_arr($a, $b) {
if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;
}
usort($array, 'sort_arr');
如果您创建一个这样的类来重用代码,那就更好了:
class FieldSorter {
public $field;
function __construct($field) {
$this->field = $field;
}
function cmp($a, $b) {
if ($a[$this->field] == $b[$this->field]) return 0;
return ($a[$this->field] > $b[$this->field]) ? 1 : -1;
}
}
$sorter = new FieldSorter('price');
usort($array, array($sorter, "cmp"));
这样,您就可以轻松地按其他字段排序。
uasort()
而不是 usort
轻松实现这一点。
这与已接受的答案基本相同,但多年来 PHP 中添加了一些新功能,以便更方便地使用
usort
。
$column = 'price';
usort($table, function($a, $b) use ($column) {
return $a[$column] <=> $b[$column];
});
您现在可以使用匿名函数进行比较回调(从 PHP 5.3 开始),并且 PHP 7 引入了组合比较运算符(
<=>
),它允许您减少比较逻辑
if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;
单个表达式
return $a[$column] <=> $b[$column];
这个问题有点老了,但将在这里留下答案以供将来使用。
来自 php.net-Multisort 函数我们可以使用下面的代码;
$data= [['volume' => 67, 'edition' => 2],['volume' => 85, 'edition' => 6],...];
foreach ($data as $key => $row) {
$volume[$key] = $row['volume'];
$edition[$key] = $row['edition'];
}
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
以上是数据的静态排序,您可以手动更改排序列。
对于更动态和强大的示例,请考虑以下;
假设我有以下数据;
$data = [[1, 'Amanda', 'Wright', '[email protected]', 'Female', '135.114.57.89', 31237],
[2, 'Theresa', 'Larson', '[email protected]', 'Female', '207.108.96.210', 91011],
[3, 'Walter', 'Kennedy', '[email protected]', 'Male', '199.147.223.56', 50114],
[4, 'Andrea', 'Richards', '[email protected]', 'Female', '230.195.124.95', 76489],
[5, 'Carol', 'Jones', '[email protected]', 'Female', '250.197.111.90', 56501],
[6, 'Alice', 'Freeman', '[email protected]', 'Female', '52.195.252.131', 77170],
[7, 'Gerald', 'Fisher', '[email protected]', 'Male', '81.2.22.62', 75625],....]
如果我们需要对上面的数组数据进行开箱即用的排序,那么我们可以使用以下语法设置数组中的排序顺序;
$qTable[$index]=$sort_order;
E.g. $qTable=[1=>'asc',4=>'desc',3=>'asc'];
这意味着对第 1 列 ASC、第 4 列 DESC 和第 3 列 ASC 进行排序。 然后我们可以使用下面的函数对多维数据库数据进行排序;
function sortMulti($data, $orders)
{
$args = [];
foreach ($data as $key => $row) {
foreach ($orders as $index => $order) {
if (!isset($row[$index])) continue; //Ignore if column does'nt exist
$args[$index]['d'][$key] = $row[$index]; //Get all values within the column
$args[$index]['o'] = 'desc' == strtolower($order) ? SORT_DESC : SORT_ASC; //Get the Sort order 'ASC' is the default
}
}
$p = [];
//Below we need to organize our entries as arguments for array_multisort
foreach ($args as $arg) {
$p[] = $arg['d'];
$p[] = $arg['o'];
//Below we need to check if column contains only numeric or not.
//If all values are numeric, then we use numeric sort flag, otherwise NATURAL
//Manipulate for more conditions supported
$p[] = count($arg['d']) == count(array_filter($arg['d'], 'is_numeric')) ? SORT_NUMERIC : SORT_NATURAL;
}
$p[] = &$data; //Pass by reference
call_user_func_array('array_multisort', $p); //Call Php's own multisort with parameters in required order.
return $data; //Our final array sorted.
}
然后我们可以如下使用它;
$data=[[...],[...],...];
$order=[1=>'asc',4=>'desc',3=>'asc'];
$sorted=sortMulti($data,$order);
对于键值数组数据
E.g. $data=[['c1'=>1212,'c2'=>'mynames'],...];
使用顺序为 $order=['c1'=>'desc','c10'=>'asc'];
我用 1000 条记录的数组测试了上面的内容。 希望它对某人有帮助。
您可以自己创建一个函数,如下所示
私有函数 orderArrayBycolumn($array, $column){
$newArray = [];
foreach ($array as $key => $value) {
$newArray[$value[$column]] = $value;
}
$array = [];
ksort($newArray);
foreach ($newArray as $key => $value) {
$array[] = $value;
}
return $array;
}
您可以将 usort 函数与回调一起使用
我只想补充几点......
@rf1234的答案可能就是我想要的(因为我在某处读到
array_multisort()
优于usort()
,但我没有亲自对它们进行基准测试),但是不需要声明排序方向,因为默认方向是ASC。
代码:(演示)
$column = 'price';
array_multisort(array_column($array, $column), $array);
var_export($array);
@Don'tPanic 使用
usort()
与宇宙飞船操作员的答案也很有吸引力。 从 PHP7.4 开始,可以使用箭头函数语法来减少语法,删除 use()
表达式。 这种技术可以让$column
自由进入函数范围,而无需use()
。
代码:(演示)
$column = 'price';
usort($array, fn($a, $b) => $a[$column] <=> $b[$column]);
var_export($array);
我推荐这些正确、高效、直接的解决方案。