按一个属性对对象数组进行排序
如何按其中一个字段(例如 name
或 count
)对这个对象数组进行排序?
Array
(
[0] => stdClass Object
(
[ID] => 1
[name] => Mary Jane
[count] => 420
)
[1] => stdClass Object
(
[ID] => 2
[name] => Johnny
[count] => 234
)
[2] => stdClass Object
(
[ID] => 3
[name] => Kathy
[count] => 4354
)
....
How can I sort this array of objects by one of its fields, like name
or count
?
Array
(
[0] => stdClass Object
(
[ID] => 1
[name] => Mary Jane
[count] => 420
)
[1] => stdClass Object
(
[ID] => 2
[name] => Johnny
[count] => 234
)
[2] => stdClass Object
(
[ID] => 3
[name] => Kathy
[count] => 4354
)
....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
使用 usort 自定义比较函数。以下是改编自手册的示例:
您还可以使用任何 callable 作为第二个参数。以下是一些示例:
使用匿名函数(从 PHP 5.3 开始) )
从类内部
使用箭头函数(从 PHP 7.4 开始)
此外,如果您要比较数值,
fn($a, $b) =>; $a->count - $b->count
作为“比较”函数应该可以解决问题,或者,如果您想要另一种方法来完成同样的事情,从 PHP 7 开始,您可以使用宇宙飞船操作员,像这样:fn($a, $b) => $a->count <=>; $b->计数
。Use usort to customize the comparison function. Here's an example adapted from the manual:
You can also use any callable as the second argument. Here are some examples:
Using anonymous functions (from PHP 5.3)
From inside a class
Using arrow functions (from PHP 7.4)
Also, if you're comparing numeric values,
fn($a, $b) => $a->count - $b->count
as the "compare" function should do the trick, or, if you want yet another way of doing the same thing, starting from PHP 7 you can use the Spaceship operator, like this:fn($a, $b) => $a->count <=> $b->count
.这是使用闭包的更好方法
请注意,这不在 PHP 文档中,但如果您使用 5.3+ 则支持闭包,其中可以提供可调用参数。
Here's a nicer way using closures
Please note this is not in PHP's documentation but if you using 5.3+ closures are supported where callable arguments can be provided.
如果您想对整数值进行排序:
更新
使用字符串不要忘记转换为相同的寄存器(高位或低位)
If you want to sort integer values:
UPDATED
with the string don't forget to convert to the same register (upper or lower)
如果您使用 php oop 您可能需要更改为:
if you're using php oop you might need to change to:
count
字段将使用相同的代码。有关
usort
的更多详细信息:https://www.php.net/usort顺便说一句,你从哪里得到这个数组?我希望不是来自数据库?
The same code will be with the
count
field.More details about
usort
: https://www.php.net/usortBtw, where did you get that array from? I hope that not from database?
要对一列值进行排序,
array_column()
和array_multisort()
的组合是一种明智的方法。 Demo或者仅使用 spaceship 运算符调用
usort()
来执行更少的迭代设想。 Demo请注意,虽然计数值在输入数组中被转换为字符串类型值,但这两个排序函数都会正确地对按数字顺序排列值,而不是按字母顺序排列(错误地将
23420
放在420
之前)。这是一个可靠的默认功能。即使您可变地声明要排序的列,这两种方法都允许在不使用任何附加技术的情况下使用变量。
带变量的多排序演示
带变量的 Usort 演示
两个原生排序函数都是通过引用进行修改的,因此不要尝试通过返回值来访问已排序的数组。
array_multisort()
的默认排序方向是升序,因此在两个数组参数之间显式使用SORT_ASC
没有任何好处。如果需要降序排序,请在两个数组之间写入SORT_DESC
(作为第二个参数)。当自定义函数体将
$a
数据放在 spaceship 运算符的左侧并将$b
数据放在 spaceship 运算符的左侧时,usort()
将以升序排序右侧。如果要按降序排序,只需在左侧写入$b
数据,在右侧写入$a
数据即可。两种方法都能够接收多个排序规则,但因为这个问题只要求对单个列进行排序,所以该指南在这里是不合适的。
排序时在每次迭代时调用函数(如
strcmp()
)会降低效率。这不再是最佳实践。也不是使用双向比较(如>
或<
)来返回布尔结果。usort()
预计会进行三向比较。对于使用多个规则/列/属性对数据进行排序,此答案提供了很好的指导。
To sort on one column of values, a combination of
array_column()
andarray_multisort()
is one sensible way. DemoOr only call upon
usort()
with the spaceship operator to perform less iterating in this scenario. DemoNotice that although the count values are cast as string type values in the input array, both sorting functions will correctly sort the values numerically instead of alphabetizing them (erroneously putting
23420
before420
). This is a reliable default feature.Even if you are variably declaring the column to sort on, both approaches allow the variable to be used without any addition techniques.
Multisort Demo with variable
Usort Demo with variable
Both native sorting functions modify by reference, so do not try to access the sorted array by their return value.
array_multisort()
's default sorting direction is ascending, so it is of no benefit to explicitly use theSORT_ASC
between the two array parameters. If descending sorting is desired, writeSORT_DESC
between the two arrays (as the second parameter).usort()
will sort ascending when the custom function body puts$a
data on the left side of the spaceship operator and$b
data on the right side. For sorting in a descending direction, just write$b
data on the left and$a
data on the right.Both approaches are capable of receiving multiple sorting rules, but because this question only asks to sort on a single column, that guidance is inappropriate here.
It will be less efficient to call a function (like
strcmp()
) on every iteration while sorting. This is no longer best practice. Neither is using a two-way comparison (like>
or<
) to return a boolean outcome. A three-way comparison is expected fromusort()
.For sorting data with multiple rules/columns/properties, this answer gives good guidance.
如果一切都失败了,这里还有另一种解决方案:
If everything fails here is another solution:
您可以使用此函数(适用于 PHP 版本 >= 5.3):
示例:
You can use this function (works in PHP Version >= 5.3):
Example:
您可以使用
usort
,如下所示:You can use
usort
, like this:如果你想对日期进行排序
if you want to sort dates
这里所有答案的缺点是它们使用静态字段名称,所以我以 OOP 风格编写了一个调整版本。假设您使用 getter 方法,您可以直接使用此类并使用字段名称作为参数。可能有人觉得它有用。
Downside of all answers here is that they use static field names, so I wrote an adjusted version in OOP style. Assumed you are using getter methods you could directly use this Class and use the field name as parameter. Probably someone find it useful.
如果需要基于本地的字符串比较,可以使用
strcoll
而不是strcmp
。请记住首先使用
setlocale
和LC_COLLATE
以根据需要设置区域设置信息。If you need local based string comparison, you can use
strcoll
instead ofstrcmp
.Remeber to first use
setlocale
withLC_COLLATE
to set locale information if needed.一个简单的替代方案,允许您动态确定排序所基于的字段:
这基于 闭包类,允许匿名函数。它从 PHP 5.3 开始可用。
A simple alternative that allows you to determine dynamically the field on which the sorting is based:
This is based on the Closure class, which allows anonymous functions. It is available since PHP 5.3.
如果您在 Codeigniter 中使用它,您可以使用以下方法:
@rmooney 谢谢您的建议。这真的对我有帮助。
If you are using this inside Codeigniter, you can use the methods:
@rmooney thank you for the suggestion. It really helps me.
感谢您的启发,我还必须添加一个外部 $translator 参数
Thanks for the inspirations, I also had to add an external $translator parameter
如果您只需要按一个字段进行排序,那么
usort
是一个不错的选择。但是,如果您需要按多个字段排序,解决方案很快就会变得混乱。在这种情况下,可以使用 YaLinqo 库*,它为数组和对象实现类似 SQL 的查询语法。它对于所有情况都有一个漂亮的语法:这里,
'$v->count'
是function ($v) { return $v->count; 的简写。 }
(都可以使用)。这些方法链返回迭代器,但如果需要,您可以通过在末尾添加->toArray()
来获取数组。* 由我开发
If you need to sort by only one field, then
usort
is a good choice. However, the solution quickly becomes messy if you need to sort by multiple fields. In this case, YaLinqo library* can be used, which implements SQL-like query syntax for arrays and objects. It has a pretty syntax for all cases:Here,
'$v->count'
is a shorthand forfunction ($v) { return $v->count; }
(either can be used). These method chains return iterators, but you can get arrays by adding->toArray()
in the end if you need it.* developed by me
您可以使用 sorted 函数Nspl:
You can use sorted function from Nspl:
这就是我的实用程序类
调用它:
This is what I have for a utility class
Call it:
你可以像这样使用usort
如果你想按数字排序:
或者 Abc char:
查看更多:https://www.php.net/manual/en/function.usort.php
You can use usort like this
If you want to sort by number:
Or Abc char:
See more: https://www.php.net/manual/en/function.usort.php
Demodave吃多键参考答案
reference answer of Demodave to eating multi key
用这个....
再见!!!!
use this....
Bye!!!!
就我而言,以下是我如何继续按对象字段对对象数组进行排序:
代码:(演示) -- 按last_name ASC 排序,然后first_name ASC
输出:
PHP7.4 及更高版本的箭头语法。
使用宇宙飞船运算符 (<=>)(又名“组合比较运算符”或“三向比较运算符”)使多列排序变得超级简单。
资源: https://wiki.php.net/rfc/combined-comparison-operator< /a>
https://stackoverflow.com/a/54647220/18090932
For my part, here is how I proceeded to sort an array of objects by object fields:
Code: (Demo) -- sorts by last_name ASC, then first_name ASC
Outpout:
Arrow syntax with PHP7.4 and higher.
Makes sorting by multiple columns SUPER easy with the spaceship operator (<=>) aka the "Combined Comparison Operator" or "Three-way Comparison Operator".
Resource: https://wiki.php.net/rfc/combined-comparison-operator
https://stackoverflow.com/a/54647220/18090932