如何按“order”键的值对该数组进行排序?
尽管这些值当前是连续的,但它们并不总是如此。
Array
(
[0] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[order] => 3
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[order] => 2
)
[2] => Array
(
[hashtag] => e7d31fc0602fb2ede144d18cdffd816b
[title] => Ready
[order] => 1
)
)
试试 usort。如果您仍在使用 PHP 5.2 或更早版本,则必须先定义一个排序函数:
function sortByOrder($a, $b) {
return $a['order'] - $b['order'];
}
usort($myArray, 'sortByOrder');
从 PHP 5.3 开始,您可以使用匿名函数:
usort($myArray, function($a, $b) {
return $a['order'] - $b['order'];
});
最后,在 PHP 7 中,您可以使用 spaceship operator:
usort($myArray, function($a, $b) {
return $a['order'] <=> $b['order'];
});
要将其扩展到多维排序,如果第一个排序元素为零,请参考第二个/第三个排序元素 - 最好在下面解释。您也可以使用它对子元素进行排序。
usort($myArray, function($a, $b) {
$retval = $a['order'] <=> $b['order'];
if ($retval == 0) {
$retval = $a['suborder'] <=> $b['suborder'];
if ($retval == 0) {
$retval = $a['details']['subsuborder'] <=> $b['details']['subsuborder'];
}
}
return $retval;
});
如果您需要保留键关联,请使用 uasort()
- 请参阅手册中的 comparison of array sorting functions。
function aasort (&$array, $key) {
$sorter = array();
$ret = array();
reset($array);
foreach ($array as $ii => $va) {
$sorter[$ii] = $va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii] = $array[$ii];
}
$array = $ret;
}
aasort($your_array, "order");
我使用这个功能:
function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
$sort_col = array();
foreach ($arr as $key => $row) {
$sort_col[$key] = $row[$col];
}
array_multisort($sort_col, $dir, $arr);
}
array_sort_by_column($array, 'order');
编辑这个答案至少有十年的历史了,现在可能有更好的解决方案,但我根据一些评论的要求添加了一些额外的信息。
它之所以有效,是因为 array_multisort()
可以对多个数组进行排序。示例输入:
Array
(
[0] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[order] => 3
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[order] => 2
)
第一个 $sort_col
是一个二维数组,其值是我们想要排序的值,键与输入数组匹配。例如对于这个输入,选择键 $sort_col
"order"
我们得到:
Array
(
[0] => 3,
[1] => 2
)
array_multisort()
然后对该数组进行排序(产生键顺序 1, 0
),但这只是二维数组。因此,原始输入数组也作为 $rest
参数传递。当键匹配时,它将被排序,因此它的键也是相同的顺序,给出所需的结果。
笔记:
它通过引用传递,以便提供的数组被修改到位。
array_multisort() 可以像这样对多个附加数组进行排序,而不仅仅是一个
为此,我们可以使用“对多维或多维数组进行排序”的“array_multisort”方法。它的方法参数是
$keys - 一个被排序的数组
SORT_ASC - 排序顺序(升序)
排序标志(通常比较项目(不要更改类型)或数字或字符串)
$new - 然后是其余的数组。仅比较与先前数组中的等效元素相对应的元素。
'sort flags' 默认是 SORT_REGULAR 并且被省略。
$new = [
[
'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4',
'title' => 'Flower',
'order' => 3,
],
[
'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594',
'title' => 'Free',
'order' => 2,
],
[
'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b',
'title' => 'Ready',
'order' => 1,
],
];
$keys = array_column($new, 'order');
array_multisort($keys, SORT_ASC, $new);
var_dump($new);
结果:
Array
(
[0] => Array
(
[hashtag] => e7d31fc0602fb2ede144d18cdffd816b
[title] => Ready
[order] => 1
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[order] => 2
)
[2] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[order] => 3
)
)
我通常使用usort,并传递我自己的比较函数。在这种情况下,它非常简单:
function compareOrder($a, $b)
{
return $a['order'] - $b['order'];
}
usort($array, 'compareOrder');
在 PHP 7 中使用 spaceship 运算符:
usort($array, function($a, $b) {
return $a['order'] <=> $b['order'];
});
要按“title”键的值对数组进行排序,请使用:
uasort($myArray, function($a, $b) {
return strcmp($a['title'], $b['title']);
});
strcmp 比较字符串。
uasort() 按照定义的方式维护数组键。
order
列进行排序。无论如何,宇宙飞船操作员(在接受的答案中演示)执行相同的比较而不进行迭代函数调用。
使用 array_multisort()
、array_map()
array_multisort(array_map(function($element) {
return $element['order'];
}, $array), SORT_ASC, $array);
print_r($array);
array_multisort
引用它的第一个参数。
array_column()
更合适/更简洁。
$sort = array();
$array_lowercase = array_map('strtolower', $array_to_be_sorted);
array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $alphabetically_ordered_array);
这会处理大写和小写字母。
最灵活的方法是使用这种方法:
Arr::sortByKeys(array $array, $keys, bool $assoc = true): array
原因如下:
您可以按任何键排序(也可以嵌套,如 'key1.key2.key3' 或 ['k1', 'k2', 'k3'])
它适用于关联数组和非关联数组($assoc 标志)
它不使用引用 - 它返回一个新的排序数组
在你的情况下,它会很简单:
$sortedArray = Arr::sortByKeys($array, 'order');
此方法是 this library 的一部分。
PHP 7.4 及更高版本的工作“箭头函数”语法:
uasort($yourArray, fn($a, $b) => $a['order'] <=> $b['order']);
漂亮的印刷品
echo '<pre>';
print_r($yourArray);
array_reverse
?
uasort($yourArray, fn($a, $b) => -1*($a['order'] <=> $b['order']));
反向...
正如接受的答案所述,您可以使用:
usort($myArray, function($a, $b) {
return $a['order'] <=> $b['order'];
});
如果您需要按多列排序,那么您将执行以下操作:
usort($myArray, function($a, $b) {
return [$a['column1'],$a['column2']] <=> [$b['column1'],$b['column2']];
});
这可以扩展到数据中的任意数量的列。这取决于您可以在 PHP 中直接比较数组这一事实。在上面的示例中,数组将首先按 column1
排序,然后按 column2
。但是您可以按任何顺序按列排序,例如:
usort($myArray, function($a, $b) {
return [$a['column2'],$a['column1']] <=> [$b['column2'],$b['column1']];
});
如果您需要对一列升序和另一列降序进行排序,则将降序列交换到运算符 <=>
的另一侧:
usort($myArray, function($a, $b) {
return [$a['column1'],$b['column2']] <=> [$b['column1'],$a['column2']];
});
如果有人需要根据键排序,最好使用以下内容:
usort($array, build_sorter('order'));
function build_sorter($key) {
return function ($a, $b) use ($key) {
return strnatcmp($a[$key], $b[$key]);
};
}
此解决方案适用于 usort(),具有易于记忆的多维排序符号。使用了宇宙飞船运算符 <=>,它可从 PHP 7 获得。
usort($in,function($a,$b){
return $a['first'] <=> $b['first'] //first asc
?: $a['second'] <=> $b['second'] //second asc
?: $b['third'] <=> $a['third'] //third desc (a b swapped!)
//etc
;
});
例子:
$in = [
['firstname' => 'Anton', 'surname' => 'Gruber', 'birthdate' => '03.08.1967', 'rank' => 3],
['firstname' => 'Anna', 'surname' => 'Egger', 'birthdate' => '04.01.1960', 'rank' => 1],
['firstname' => 'Paul', 'surname' => 'Mueller', 'birthdate' => '15.10.1971', 'rank' => 2],
['firstname' => 'Marie', 'surname' => 'Schmidt ', 'birthdate' => '24.12.1963', 'rank' => 2],
['firstname' => 'Emma', 'surname' => 'Mueller', 'birthdate' => '23.11.1969', 'rank' => 2],
];
第一项任务:按等级升序,姓氏升序排序
usort($in,function($a,$b){
return $a['rank'] <=> $b['rank'] //first asc
?: $a['surname'] <=> $b['surname'] //second asc
;
});
第二个任务:按等级 desc、姓氏 asc、firstmame asc 排序
usort($in,function($a,$b){
return $b['rank'] <=> $a['rank'] //first desc
?: $a['surname'] <=> $b['surname'] //second asc
?: $a['firstname'] <=> $b['firstname'] //third asc
;
});
第三项任务:按等级降序排列,生日升序排列
日期不能用这种表示法排序。它是用 strtotime 转换的。
usort($in,function($a,$b){
return $b['rank'] <=> $a['rank'] //first desc
?: strtotime($a['birthdate']) <=> strtotime($b['birthdate']) //second asc
;
});
您可以使用 usort
和带有回调函数的用户定义排序函数:
usort($new, fn($a, $b) => $a['order'] - $b['order']);
TRICK:您可以使用 a > b
或 a - b
或 a <=> b
按升序顺序进行排序。对于 降序 订单,只需 a
和 b
的交换位置。
我发现这很有帮助:
$columns = array_column($data, "order");
array_multisort($columns, SORT_ASC, $data);
让我们面对现实吧:PHP 没有一个简单的开箱即用的函数来正确处理每个数组排序场景。
这个例程很直观,这意味着更快的调试和维护:
// Automatic population of the array
$tempArray = array();
$annotations = array();
// ... some code
// SQL $sql retrieves result array $result
// $row[0] is the ID, but is populated out of order (comes from
// multiple selects populating various dimensions for the same DATE
// for example
while($row = mysql_fetch_array($result)) {
$needle = $row[0];
arrayIndexes($needle); // Create a parallel array with IDs only
$annotations[$needle]['someDimension'] = $row[1]; // Whatever
}
asort($tempArray);
foreach ($tempArray as $arrayKey) {
$dataInOrder = $annotations[$arrayKey]['someDimension'];
// .... more code
}
function arrayIndexes ($needle) {
global $tempArray;
if (!in_array($needle, $tempArray)) {
array_push($tempArray, $needle);
}
}
global
是一个巨大的危险信号,是 generally discouraged。为什么为这个问题演示 mysql_fetch_array
而不是 OP 的源数组,并且没有解释您的代码在做什么以及可以预期结果是什么?总体而言,这是一种非常复杂的方法来实现预期的最终结果。
global
请参阅: 3v4l.org/FEeFC 这会生成一个明确定义的变量,而不是一个可以全局更改和访问的变量。
?:
(三元运算符)。 3 这样就不会不必要地调用额外的函数。