PHP中按列值对数组进行排序:厌倦了搜索的开发者的指南
\n\n你是否曾经遇到过这样的情况:你有一个用户、商品或订单列表,以关联数组的形式存在,需要按某个字段进行排序?比如按年龄、价格或注册日期。如果是的话——你并不孤单。这个问题在Stack Overflow上获得了数千次浏览和数十个赞。今天,我们将一劳永逸地解决它。
\n\n在这篇文章中,我们不仅会展示usort和array_multisort是如何工作的。我们还会回答开发者最常遇到的问题:如何按嵌套键排序,如何保留键,如何按多个字段排序,以及如果数据来自数据库该怎么办。
开始吧!
\n\n什么是关联数组的数组,为什么要对它排序?
\n\n假设你有一个用户列表:
\n\n$users = [\n ['name' => '安娜', 'age' => 25, 'city' => '莫斯科'],\n ['name' => '鲍里斯', 'age' => 30, 'city' => '圣彼得堡'],\n ['name' => '维克多', 'age' => 22, 'city' => '喀山'],\n];\n\n这是一个典型的PHP多维数组,其中每个元素都是一个具有相同键的关联数组。通常需要按某个字段对这个列表进行排序:按年龄(从小到大)、按姓名(字母顺序)或按城市。
\n\n像sort()或asort()这样的标准PHP函数在这里帮不上忙——它们处理的是简单值,而不是嵌套结构。我们需要专门的工具。
最流行的方法:使用匿名函数的usort
\n\n如果你访问Stack Overflow并打开关于"Sort an array of associative arrays by column value"的讨论,90%的情况下你会被推荐使用usort。这很合理:usort函数允许你定义自己的比较两个数组元素的逻辑。
如何按单个字段(年龄)对数组排序
\n\n假设我们想按年龄升序对用户进行排序:
\n\n<?php\n$users = [\n ['name' => '安娜', 'age' => 25, 'city' => '莫斯科'],\n ['name' => '鲍里斯', 'age' => 30, 'city' => '圣彼得堡'],\n ['name' => '维克多', 'age' => 22, 'city' => '喀山'],\n];\n\nusort($users, function($a, $b) {\n return $a['age'] <=> $b['age'];\n});\n\nprint_r($users);\n?>\n\n结果:
\nArray\n(\n [0] => Array ( [name] => 维克多 [age] => 22 [city] => 喀山 )\n [1] => Array ( [name] => 安娜 [age] => 25 [city] => 莫斯科 )\n [2] => Array ( [name] => 鲍里斯 [age] => 30 [city] => 圣彼得堡 )\n)\n\n请注意:我们使用了太空船操作符<=>,它从PHP 7开始引入。它返回-1、0或1,非常适合排序函数。如果需要按降序排序,只需交换$a和$b的位置:
usort($users, function($a, $b) {\n return $b['age'] <=> $a['age'];\n});\n\n按字符串字段(姓名)排序
\n\n对于字符串,同样简单。想按字母顺序对用户按姓名排序?没问题:
\n\nusort($users, function($a, $b) {\n return strcmp($a['name'], $b['name']);\n});\n\n或者再次使用<=>——它也适用于字符串:
usort($users, function($a, $b) {\n return $a['name'] <=> $b['name'];\n});\n\n常见问题和陷阱
\n\n1. 如何按嵌套键排序?
\n\n有时数据具有更深层的结构。例如,每个用户都有一个profile数组