如何按 PHP 中内部数组的字段之一对多维数组进行排序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2426917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I sort a multidimensional array by one of the fields of the inner array in PHP?
提问by Camsoft
Suppose I have an array that mimics a database table. Each array element represents a row, and within each row is another array that contains the field names and values.
假设我有一个模拟数据库表的数组。每个数组元素代表一行,每行内是另一个包含字段名称和值的数组。
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
)
}
What I want to do is sort the rows (outer array elements) by price. Below is an example of what I want to achieve:
我想要做的是按价格对行(外部数组元素)进行排序。下面是我想要实现的一个例子:
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
)
}
As you can see, I don't need to preserve the keys of the outer array.
如您所见,我不需要保留外部数组的键。
回答by Dancrumb
回答by rf1234
It is just a one liner
它只是一个班轮
array_multisort( array_column($yourArray, "price"), SORT_ASC, $yourArray );
You can find it here as well: http://php.net/manual/en/function.array-multisort.php
你也可以在这里找到它:http: //php.net/manual/en/function.array-multisort.php
search for "array_column" on that manual page.
在该手册页上搜索“array_column”。
回答by Felix Kling
You can use usort():
您可以使用usort():
function sort($a, $b) {
if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;
}
usort($array, 'sort');
Even better if you create a class like this to reuse the code:
如果你创建一个这样的类来重用代码,那就更好了:
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"));
This way, you can easily sort by other fields.
这样,您可以轻松地按其他字段排序。
And although you said the the keys of the outer array don't have to be preserved you can easily achieve this by using uasort()instead of usort.
尽管您说不必保留外部数组的键,但您可以通过使用uasort()代替usort.
回答by Don't Panic
This is basically the same as the accepted answer, but a couple of new features have been added to PHP over the years to make it more convenient to use usortfor this.
这与接受的答案基本相同,但多年来 PHP 中添加了一些新功能,以使其更方便地使用usort。
$column = 'price';
usort($table, function($a, $b) use ($column) {
return $a[$column] <=> $b[$column];
});
You can now use an anonymous functionfor the comparison callback (as of PHP 5.3), and PHP 7 introduced the combined comparison operator(<=>), which allows you to reduce the comparison logic
您现在可以为比较回调使用匿名函数(从 PHP 5.3 开始),并且 PHP 7 引入了组合比较运算符( <=>),它允许您减少比较逻辑
if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;
to a single expression
到单个表达式
return $a[$column] <=> $b[$column];
回答by McAngujo
This question is a bit old, but will leave the answer here for future.
这个问题有点老了,但将在这里留下答案以备将来使用。
From php.net-Multisortfunction we can use the code below;
从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);
The above is for a static sorting of data where you manually change sort columns.
以上是针对数据的静态排序,您可以在其中手动更改排序列。
For more dynamic and robust example consider below;
有关更动态和健壮的示例,请考虑以下内容;
Assume I have the data below;
假设我有以下数据;
$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],....]
If we need to sort the above array data out of the box, then we can set the sort orders in an array using the syntax;
如果我们需要开箱即用对上述数组数据进行排序,那么我们可以使用语法设置数组中的排序顺序;
$qTable[$index]=$sort_order;
E.g. $qTable=[1=>'asc',4=>'desc',3=>'asc'];
This means sort column 1 ASC, column 4 DESC then column 3 ASC. We can then using the function below to sort our multidimension database data;
这意味着对第 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.
}
Then we can use it as below;
然后我们可以如下使用它;
$data=[[...],[...],...];
$order=[1=>'asc',4=>'desc',3=>'asc'];
$sorted=sortMulti($data,$order);
For key value array data E.g. $data=[['c1'=>1212,'c2'=>'mynames'],...];Use the order as $order=['c1'=>'desc','c10'=>'asc'];
对于键值数组数据E.g. $data=[['c1'=>1212,'c2'=>'mynames'],...];使用顺序为$order=['c1'=>'desc','c10'=>'asc'];
I tested the above with an array of 1000 records. Hope it helps someone.
我用 1000 条记录的数组测试了上述内容。希望它可以帮助某人。
回答by Vals
You can use the usort function with a callback
您可以使用带有回调的 usort 函数
回答by Claudio Melo
You can create a function yourself like the one below
您可以自己创建一个函数,如下所示
private function orderArrayBycolumn($array, $column){
私有函数 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;
}
回答by mickmackusa
I just want to make a couple additions...
我只是想补充几点...
@rf1234's answer is probably what I would go for (because I read somewhere that array_multisort()outperforms usort(), but I haven't personally benchmarked them), but the sorting direction does not need to be declared because the default direction is ASC.
@rf1234 的答案可能是我想要的(因为我在某处读到了array_multisort()优于usort(),但我没有亲自对它们进行基准测试),但是不需要声明排序方向,因为默认方向是 ASC。
Code: (Demo)
代码:(演示)
$column = 'price';
array_multisort(array_column($array, $column), $array);
var_export($array);
@Don'tPanic's answer using usort()with the spaceship operator is also attractive. From PHP7.4, the syntax can be reduced and the use()expression can be removed by using arrow function syntax. This technique allows $columnto freely enter the function scope without use().
@Don'tPanicusort()与飞船操作员一起使用的答案也很有吸引力。从PHP7.4开始,可以use()使用箭头函数语法减少语法,去掉表达式。这种技术允许$column在没有use().
Code: (Demo)
代码:(演示)
$column = 'price';
usort($array, fn($a, $b) => $a[$column] <=> $b[$column]);
var_export($array);
I recommend either of these correct, efficient, direct solutions.
我推荐这些正确、高效、直接的解决方案中的任何一个。

