Php 按对象字段对对象数组排序
如何按照对象数组的某个字段(如Php 按对象字段对对象数组排序,php,arrays,sorting,object,Php,Arrays,Sorting,Object,如何按照对象数组的某个字段(如name或count)对该数组进行排序 Array ( [0] => stdClass Object ( [ID] => 1 [name] => Mary Jane [count] => 420 ) [1] => stdClass Object ( [ID] => 2
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
)
....
usort($array,'my_sort_function');
变量转储($数组);
函数my_sort_函数($a,$b)
{
返回$a->name<$b->name;
}
count
字段将使用相同的代码
有关usort的更多详细信息:
顺便说一句,你从哪里得到的数组?我希望不是来自数据库?使用,下面是一个改编自手册的示例:
function cmp($a, $b) {
return strcmp($a->name, $b->name);
}
usort($your_data, "cmp");
您还可以使用any作为第二个参数。以下是一些例子:
- 使用(来自PHP5.3)
- 从班级内部
usort($your_data, array($this, "cmp")); // "cmp" should be a method in the class
- 使用(来自PHP7.4)
此外,如果您正在比较数值,
fn($a,$b)=>a->count-$b->count
作为“compare”函数应该可以实现这一点,或者,如果您想用另一种方法来做同样的事情,从PHP7开始,您可以使用,如下所示:fn($a,$b)=>a->count count$b->count
usort($your_data, function($a, $b)
{
return strcmp($a->name, $b->name);
});
请注意,PHP文档中没有这一点,但如果您使用的是5.3+闭包,并且可以提供可调用参数。如果您使用的是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'));
如果需要基于本地的字符串比较,可以使用而不是strcmp
请记住,如果需要,请首先使用LC\u 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);
});
如果您正在使用此内部Codeigniter,则可以使用以下方法:
usort($jobs, array($this->job_model, "sortJobs")); // function inside Model
usort($jobs, array($this, "sortJobs")); // Written inside Controller.
@谢谢你的建议。它确实帮助了我。如果只需要按一个字段排序,那么usort
是一个不错的选择。但是,如果需要按多个字段排序,解决方案很快就会变得混乱。在本例中,可以使用library*,它为数组和对象实现类似SQL的查询语法。对于所有情况,它都有一个漂亮的语法:
$sortedByName = from($objects)->orderBy('$v->name');
$sortedByCount = from($objects)->orderBy('$v->count');
$sortedByCountAndName = from($objects)->orderBy('$v->count')->thenBy('$v->name');
这里,'$v->count'
是函数($v){return$v->count;}
的简写形式(可以使用任意一种)。这些方法链返回迭代器,但如果需要,可以通过在最后添加->toArray()
来获得数组
*由我开发的这里所有答案的缺点是它们使用静态字段名,所以我以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;
}
}
您可以从以下位置使用该功能:
感谢您的启发,我还必须添加一个外部$translator参数
usort($listable_products, function($a, $b) {
global $translator;
return strcmp($a->getFullTitle($translator), $b->getFullTitle($translator));
});
您可以使用此函数(适用于PHP版本>=5.3):
您可以使用usort
,如下所示:
usort($array,function($first,$second){
return strcmp($first->name, $second->name);
});
如果要对整数值进行排序:
// Desc sort
usort($array,function($first,$second){
return $first->number < $second->number;
});
// Asc sort
usort($array,function($first,$second){
return $first->number > $second->number;
});
//描述排序
usort($array,function($first,$second){
返回$first->number<$second->number;
});
//Asc排序
usort($array,function($first,$second){
返回$first->number>$second->number;
});
已更新
使用字符串时,不要忘记将其转换为相同的寄存器(上限或下限)
//描述排序
usort($array,function($first,$second){
返回strtolower($first->text)text);
});
//Asc排序
usort($array,function($first,$second){
返回strtolower($first->text)>strtolower($second->text);
});
如果一切都失败,这里有另一个解决方案:
$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;
如果你想对日期进行排序
usort($threads,function($first,$second){
return strtotime($first->dateandtime) < strtotime($second->dateandtime);
});
usort($threads,function($first,$second){
返回strotime($first->dateandtime)dateandtime);
});
一个简单的替代方案,允许您动态确定排序所基于的字段:
$order_by = 'name';
usort($your_data, function ($a, $b) use ($order_by)
{
return strcmp($a->{$order_by}, $b->{$order_by});
});
这是基于的,它允许匿名函数。它是从PHP5.3开始提供的。这是我对实用程序类的要求
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");
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
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");
你可以像这样使用usort
如果要按编号排序:
Util::sortArrayByName($array, "array_property_name");
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
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");
请参阅更多信息:Demave到eating多键的参考答案
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;
}
如果成功,$result
将包含TRUE
,您的比较应该是$a->name>$b->name
:)@坎布拉卡:哦,忘了它通过引用接受数组。顺便说一句,OP没有说他需要按哪个顺序对集合进行排序。是的,这是一个数据库:)实际上来自一个函数,该函数从database@Alex:那你为什么不在数据库里排序呢<代码>按计数排序
更复杂,因为这是wordpress的标准功能部分,在我编写插件时,我无法更改wp文件。我使用create_函数尝试了您的示例(因为我在类中使用它,不知道如何将函数名传递给usort):create_函数(“$a,$b”,“return$a->count<$b->count;”)
但我无法让它工作:(我收到一些通知和警告,usort希望参数2是一个有效的回调。我更喜欢这个参数,因为我们可以快速定义比较函数,并可以在类中使用。如果您想保留数组键,请使用uasort()
进行排序描述,-1*strcmp($a->name,$b->name);
无需乘法对desc进行排序。只需交换参数:strcmp($b->name,$a->name)
您可能会遇到像我这样的情况,接受的答案比这个答案更可取。例如,您可能有一个父类和一个子类。子类重写使用usort
的函数,但比较函数是相同的。使用此函数,您需要复制闭包的代码,而不是调用受保护的静态方法只需在父类中定义一次。这很好,但如果排序函数与调用函数在同一类中,则应使用:usort($your_data,array($This,“cmp”));@rmooney是的,但仅当您在类中时。如果您正在比较的模型/对象中有比较函数(我认为这是一种更干净的设计),请将
Util::sortArrayByName($array, "array_property_name");
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
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");
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;
}
$array[0] = array('key_a' => 'z', 'key_b' => 'c');
$array[1] = array('key_a' => 'x', 'key_b' => 'b');
$array[2] = array('key_a' => 'y', 'key_b' => 'a');
function build_sorter($key) {
return function ($a, $b) use ($key) {
return strnatcmp($a[$key], $b[$key]);
};
}
usort($array, build_sorter('key_b'));