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
)
....
#1 楼
使用usort,这是从手册改编而成的示例:function cmp($a, $b) {
return strcmp($a->name, $b->name);
}
usort($your_data, "cmp");
还可以将任何callable用作第二个参数。以下是一些示例:
使用匿名函数(来自PHP 5.3)
usort($your_data, function($a, $b) {return strcmp($a->name, $b->name);});
从类内部
usort($your_data, array($this, "cmp")); // "cmp" should be a method in the class
使用箭头函数(来自PHP 7.4)
usort($your_data, fn($a, $b) => strcmp($a->name, $b->name));
此外,如果要比较数值,则
fn($a, $b) => $a->count - $b->count
为“比较”功能应该可以解决问题,或者,如果您想以另一种方式做同样的事情,则可以从PHP 7开始使用Spaceship运算符,如下所示:fn($a, $b) => $a->count <=> $b->count
。#2 楼
这是使用闭包的一种更好的方法usort($your_data, function($a, $b)
{
return strcmp($a->name, $b->name);
});
请注意,这不在PHP的文档中,但是如果您使用的是5.3+闭包,并且可以提供可调用参数,则闭包。 >
评论
我比接受的答案更好,因为我们可以快速定义比较函数并可以在类中使用
– Nam G VU
2012年5月1日18:43
如果要保留数组键,请使用uasort()
– Gillytech
2015年5月1日,0:36
对于desc排序,-1 * strcmp($ a-> name,$ b-> name);
–华莱士·麦克特斯(Wallace Maxters)
15年7月14日在13:59
无需乘以排序desc。只是交换参数:strcmp($ b-> name,$ a-> name)
–zxcat
16 Mar 19 '16 at 0:53
您可能会遇到像我这样的情况,在这种情况下,可接受的答案比这个答案更可取。例如,您可能有一个父类和一个子类。子类会覆盖使用usort的函数,但比较函数是相同的。使用此方法,您需要复制闭包的代码,而不是调用受保护的静态方法,而只需要在父类中定义一次即可。
–佩雷
16-09-28在15:12
#3 楼
如果要对整数值进行排序:// Desc sort
usort($array,function($first,$second){
return $first->number < $second->number;
});
// Asc sort
usort($array,function($first,$second){
return $first->number > $second->number;
});
UPDATED
用字符串不要忘记转换为相同的寄存器(高位或低位)
// Desc sort
usort($array,function($first,$second){
return strtolower($first->text) < strtolower($second->text);
});
// Asc sort
usort($array,function($first,$second){
return strtolower($first->text) > strtolower($second->text);
});
#4 楼
如果您使用的是php oop,则可能需要更改为:public static function cmp($a, $b)
{
return strcmp($a->name, $b->name);
}
//in this case FUNCTION_NAME would be cmp
usort($your_data, array('YOUR_CLASS_NAME','FUNCTION_NAME'));
#5 楼
usort($array, 'my_sort_function');
var_dump($array);
function my_sort_function($a, $b)
{
return $a->name < $b->name;
}
count
字段将使用相同的代码。有关
usort
的更多详细信息:http://ru2.php.net/usort 顺便说一句,您是从哪里获得该阵列的?我希望不是来自数据库吗?
评论
如果成功,实际上$ result将包含TRUE,并且您的比较应该是$ a-> name> $ b-> name。 :)
–坎布拉卡
10 Nov 26'3:56
@cambraca:哦,忘了它接受引用数组。顺便说一句,OP没有说他需要对收集进行排序的顺序。
–zerkms
10 Nov 26'3:57
是的,这是一个数据库:)实际上是从从数据库获取数据的函数中
– Alex
10 Nov 26'4:01
@Alex:那为什么不对数据库进行排序呢?按计数排序
–zerkms
2010-11-26 4:02
它更复杂,因为这是wordpress的标准功能部分,并且在编写插件时,无法更改wp文件。我使用create_function尝试了您的示例(因为我正在类中使用它,并且我不知道如何将函数名传递给usort):create_function('$ a,$ b',“ return $ a-> count < $ b-> count;“),但我无法使其工作:(我收到一些通知,并警告usort期望参数2为有效的回调
– Alex
2010-11-26 4:11
#6 楼
您可以使用此功能(在PHP版本> = 5.3中可用):function sortArrayByKey(&$array,$key,$string = false,$asc = true){
if($string){
usort($array,function ($a, $b) use(&$key,&$asc)
{
if($asc) return strcmp(strtolower($a{$key}), strtolower($b{$key}));
else return strcmp(strtolower($b{$key}), strtolower($a{$key}));
});
}else{
usort($array,function ($a, $b) use(&$key,&$asc)
{
if($a[$key] == $b{$key}){return 0;}
if($asc) return ($a{$key} < $b{$key}) ? -1 : 1;
else return ($a{$key} > $b{$key}) ? -1 : 1;
});
}
}
示例:
sortArrayByKey($yourArray,"name",true); //String sort (ascending order)
sortArrayByKey($yourArray,"name",true,false); //String sort (descending order)
sortArrayByKey($yourArray,"id"); //number sort (ascending order)
sortArrayByKey($yourArray,"count",false,false); //number sort (descending order)
评论
我使用$ a-> {$ key}和$ b-> {$ key}而不是$ a [$ key]和$ b [$ key],因为严格来讲,我们是在处理属性而不是数组成员,但是这仍然是我一直在寻找的答案。
–SteJ
16年11月19日在15:19
请在示例代码中实现@SteJ的建议,因为您提供的解决方案仅适用于简单的对象,但通过SteJ的修复,它适用于我尝试过的所有对象数组
–user2993145
17年6月8日在15:22
#7 楼
如果一切失败,这里是另一种解决方案:$names = array();
foreach ($my_array as $my_object) {
$names[] = $my_object->name; //any object field
}
array_multisort($names, SORT_ASC, $my_array);
return $my_array;
评论
您应该为此解决方案获得奥斯卡奖! ))))) 谢谢
–Imeksbank
19年7月25日在17:11
#8 楼
您可以使用usort
,例如:usort($array,function($first,$second){
return strcmp($first->name, $second->name);
});
#9 楼
这里所有答案的缺点是它们使用静态字段名称,因此我以OOP风格编写了调整后的版本。假设您使用的是getter方法,则可以直接使用此类并使用字段名称作为参数。可能有人觉得它有用。class CustomSort{
public $field = '';
public function cmp($a, $b)
{
/**
* field for order is in a class variable $field
* using getter function with naming convention getVariable() we set first letter to uppercase
* we use variable variable names - $a->{'varName'} would directly access a field
*/
return strcmp($a->{'get'.ucfirst($this->field)}(), $b->{'get'.ucfirst($this->field)}());
}
public function sortObjectArrayByField($array, $field)
{
$this->field = $field;
usort($array, array("Your\Namespace\CustomSort", "cmp"));;
return $array;
}
}
#10 楼
如果要对日期进行排序 usort($threads,function($first,$second){
return strtotime($first->dateandtime) < strtotime($second->dateandtime);
});
#11 楼
一个简单的替代方法使您可以动态确定排序所基于的字段:$order_by = 'name';
usort($your_data, function ($a, $b) use ($order_by)
{
return strcmp($a->{$order_by}, $b->{$order_by});
});
这基于Closure类,该类允许使用匿名函数。自PHP 5.3起可用。
#12 楼
如果需要基于本地的字符串比较,则可以使用strcoll
而不是strcmp
。如果需要,请先将
setlocale
与LC_COLLATE
一起使用以设置区域设置信息。 usort($your_data,function($a,$b){
setlocale (LC_COLLATE, 'pl_PL.UTF-8'); // Example of Polish language collation
return strcoll($a->name,$b->name);
});
#13 楼
如果在Codeigniter中使用此方法,则可以使用以下方法:usort($jobs, array($this->job_model, "sortJobs")); // function inside Model
usort($jobs, array($this, "sortJobs")); // Written inside Controller.
@rmooney谢谢您的建议。真的对我有帮助。
评论
此Codeigniter具体如何?
–ggdx
18年8月10日在11:37
#14 楼
感谢您的启发,我还必须添加一个外部$ translator参数usort($listable_products, function($a, $b) {
global $translator;
return strcmp($a->getFullTitle($translator), $b->getFullTitle($translator));
});
#15 楼
如果您只需要按一个字段排序,那么usort
是一个不错的选择。但是,如果您需要按多个字段进行排序,则解决方案很快就会变得混乱。在这种情况下,可以使用YaLinqo库*,该库为数组和对象实现类似于SQL的查询语法。它在所有情况下都具有漂亮的语法:$sortedByName = from($objects)->orderBy('$v->name');
$sortedByCount = from($objects)->orderBy('$v->count');
$sortedByCountAndName = from($objects)->orderBy('$v->count')->thenBy('$v->name');
这里,
'$v->count'
是function ($v) { return $v->count; }
的简写(均可使用)。这些方法链返回迭代器,但是如果需要,可以在最后添加->toArray()
来获得数组。*由我开发的
#16 楼
您可以使用Nspl中的排序功能:use function \nspl\a\sorted;
use function \nspl\op\propertyGetter;
use function \nspl\op\methodCaller;
// Sort by property value
$sortedByCount = sorted($objects, propertyGetter('count'));
// Or sort by result of method call
$sortedByName = sorted($objects, methodCaller('getName'));
评论
请说明为什么OP需要一个完整的附加库来提供看似由内置函数解决的功能
–ggdx
18年8月10日在11:36
#17 楼
这是我为实用程序类所拥有的class Util
{
public static function sortArrayByName(&$arrayToSort, $meta) {
usort($arrayToSort, function($a, $b) use ($meta) {
return strcmp($a[$meta], $b[$meta]);
});
}
}
调用它:
Util::sortArrayByName($array, "array_property_name");
#18 楼
您可以像这样使用usort如果要按数字排序:
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
或Abc字符:
function cmp($a, $b)
{
return strcmp($a["fruit"], $b["fruit"]);
}
$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";
usort($fruits, "cmp");
查看更多:https://www.php.net/manual/zh/function.usort.php
#19 楼
Demodave吃多键的参考答案 function array_sort_by(array $arr, $keys){
if(!is_array($keys))
$keyList = explode(',', $keys);
$keyList = array_keys(array_flip($keyList)); // array_unique
$keyList = array_reverse($keyList);
$result = &$arr;
foreach ($keyList as $key) {
if(array_key_exists($key, $arr))
$result = usort($result, function($a, $b) use ($key) { return strcmp($a->{$key}, $b->{$key}); });
}
return $result;
}
评论
这很好,但是如果排序函数与调用函数在同一类中,则应使用:usort($ your_data,array($ this,“ cmp”));
–rmooney
2013年9月20日20:53
@rmooney是的,但仅当您在课堂上时。
–坎布拉卡
13年9月20日在22:37
在您的回答中加上@rmooney的第一条评论
–穆罕默德·费萨尔(Mohammad Faisal)
14年2月18日在12:57
或者,如果您的比较函数在要比较的模型/对象中(我认为这是一种更简洁的设计),则必须像这样将完整的命名空间包括到模型/对象中:uasort($ members,array(“ Path \ to \ your \ Model \ Member“,” compareByName“));
–clauziere
2014年4月4日19:04
这不会给我任何排序,只是最大的排序,其余所有我都无法排序
– AlbertoAcuña
16-10-22在12:21