通过 usort 对多维数组进行排序
Sort multidimensional array by usort
我想创建通用函数来对多维数组进行排序。
例如:我有这个数组
$arr = [
[
'product' => [
'id' => 32,
],
'price' => 23.8,
],
[
'product' => [
'id' => 2,
],
'price' => 150,
],
];
我需要按 $arr[0]['product']['id']
排序。我想像这样使用 sort smthg:usort($arr, sortArray('product.id', 'desc'));
你能告诉我怎么做吗?
将 DESC
更改为:
return $a['product']['id'] - $b['product']['id'];
将 ASC
更改为:
return $b['product']['id'] - $a['product']['id'];
试试这个代码:
<?php
$arrrrr = [
[
'product' => [
'id' => 32,
],
'price' => 23.8,
],
[
'product' => [
'id' => 2,
],
'price' => 150,
],
];
$args = array('product.id','asc');//define an array of args
usort($arrrrr, function($a, $b) use ($args) {
$firstVal = explode(".",$args[0]);
if($args[1]=='desc'){
return $a[$firstVal[0]][$firstVal[1]] - $b[$firstVal[0]][$firstVal[1]];
}else{
return $b[$firstVal[0]][$firstVal[1]] - $a[$firstVal[0]][$firstVal[1]];
}
});
echo '<pre>';print_r($arrrrr);echo '</pre>';
?>
预期输出:
Array
(
[0] => Array
(
[product] => Array
(
[id] => 2
)
[price] => 150
)
[1] => Array
(
[product] => Array
(
[id] => 32
)
[price] => 23.8
)
)
其中的关键部分是编写一个访问器函数,该函数从您的数据中获取单行以及点表示法中的 "path",例如rating.top
.
$accessor = function($row, $path) {
$steps = explode('.', $path);
$return = $row[array_shift($steps)];
while ($level = array_shift($steps)) {
$return =& $return[$level];
}
return $return;
};
这会随着路径的每一步更深入地迭代到数组中,并解析为末尾的值。它适用于任意数量的步骤,例如 user.rating.top.foo.var.whatever
。它本质上是 Symfony's PropertyAccess component.
的精简版
使用此方法,您可以构建一个回调以传递给 usort
,该回调将比较来自被比较的两个元素的访问值。
usort($array, function ($a, $b) use ($field, $accessor) {
$aVal = $accessor($a, $field);
$bVal = $accessor($b, $field);
return $aVal <=> $bVal;
});
您可以在此处查看完整的版本:https://3v4l.org/UciGc
我想创建通用函数来对多维数组进行排序。 例如:我有这个数组
$arr = [
[
'product' => [
'id' => 32,
],
'price' => 23.8,
],
[
'product' => [
'id' => 2,
],
'price' => 150,
],
];
我需要按 $arr[0]['product']['id']
排序。我想像这样使用 sort smthg:usort($arr, sortArray('product.id', 'desc'));
你能告诉我怎么做吗?
将 DESC
更改为:
return $a['product']['id'] - $b['product']['id'];
将 ASC
更改为:
return $b['product']['id'] - $a['product']['id'];
试试这个代码:
<?php
$arrrrr = [
[
'product' => [
'id' => 32,
],
'price' => 23.8,
],
[
'product' => [
'id' => 2,
],
'price' => 150,
],
];
$args = array('product.id','asc');//define an array of args
usort($arrrrr, function($a, $b) use ($args) {
$firstVal = explode(".",$args[0]);
if($args[1]=='desc'){
return $a[$firstVal[0]][$firstVal[1]] - $b[$firstVal[0]][$firstVal[1]];
}else{
return $b[$firstVal[0]][$firstVal[1]] - $a[$firstVal[0]][$firstVal[1]];
}
});
echo '<pre>';print_r($arrrrr);echo '</pre>';
?>
预期输出:
Array
(
[0] => Array
(
[product] => Array
(
[id] => 2
)
[price] => 150
)
[1] => Array
(
[product] => Array
(
[id] => 32
)
[price] => 23.8
)
)
其中的关键部分是编写一个访问器函数,该函数从您的数据中获取单行以及点表示法中的 "path",例如rating.top
.
$accessor = function($row, $path) {
$steps = explode('.', $path);
$return = $row[array_shift($steps)];
while ($level = array_shift($steps)) {
$return =& $return[$level];
}
return $return;
};
这会随着路径的每一步更深入地迭代到数组中,并解析为末尾的值。它适用于任意数量的步骤,例如 user.rating.top.foo.var.whatever
。它本质上是 Symfony's PropertyAccess component.
使用此方法,您可以构建一个回调以传递给 usort
,该回调将比较来自被比较的两个元素的访问值。
usort($array, function ($a, $b) use ($field, $accessor) {
$aVal = $accessor($a, $field);
$bVal = $accessor($b, $field);
return $aVal <=> $bVal;
});
您可以在此处查看完整的版本:https://3v4l.org/UciGc