在PHP中按对象属性对数组进行排序?

58
如果我有这样一个对象:
class Person {
  var $age;
  function __construct($age) {
    $this->age = $age;
  }
}

我有一个 Person 数组

$person1 = new Person(14);
$person2 = new Person(5);
$people = array($person1, $person2);

有没有一种简单的方法可以按照Person->age属性对$people数组进行排序?


我正在尝试避免使用usort(),因为随着我的people数组的增长,它是一个过于昂贵的调用。假设$people中有15,000个条目。 - skcubrats
你认为usort有什么低效之处,需要通过其他方法来避免?usort会原地排序,并且应该非常高效。 - Paul Dixon
每次调用都会创建一个函数,这在大数据集中效率低下。 - skcubrats
1
我已经发布了一些基准测试细节 - usort并不算太糟糕,但确实可以使用非递归快速排序来获得更快的速度。 - Paul Dixon
你在做什么需要一次性排序15000个对象? - Gumbo
15个回答

1
尝试使用 usort:http://www.php.net/manual/zh/function.usort.php 例子:
<?php
function cmp($obja, $objb)
{
    $a = $obja->sortField;
    $b = $objb->sortField;
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = array( /* your objects */ );

usort($a, "cmp");

?>

1
如果所有的成员变量都保证不同,那么创建一个以这些值为索引的新集合,然后对其进行ksort排序将更简单、更快速:
 foreach($obj_list as $obj)
    $map[$obj->some_var] = $obj;
 ksort($map);
 /// $map now contains the sorted list

如果存在重复值,您仍然可以通过利用 sort 的一个不太知名的特性来避免使用 usort。这个特性是,数组中的数组按照第一个标量成员的值进行排序。
 foreach($obj_list as $obj)
    $map[] = array($obj->some_var, $obj);
 sort($map); // sorts $map by the value of ->some_var

我猜这仍然比usort快10000000倍。


1
1000次是一个毫无底线的夸张。 - Gordon
2
如果两个或多个实例的两个或多个属性相同怎么办? - Tim

1

是的。如果在您的个人对象中实现spl ArrayObject,则所有正常的PHP数组函数都可以与其正常工作。


1

usort()uasort() /* 如果您正在使用关联数组,则维护索引关联 */


0

这里有一个选项,考虑以下几点:

  • 命名空间
  • 私有属性
  • 使用getter和setter方法
  • 将排序属性作为参数

PHP

namespace Dummy;

class Person {

    private $age;

    function __construct($age) {
        $this->setAge($age);
    }

    public function getAge()
    {
        return $this->age;
    }

    public function setAge($age)
    {
        $this->age = $age;
    }
}

class CustomSort{

    public $field = '';

    public function cmp($a, $b)
    {
        return strcmp($a->{'get'.ucfirst($this->field)}(), $b->{'get'.ucfirst($this->field)}());
    }

    public function sortObjectArrayByField($array, $field)
    {
        $this->field = $field;
        usort($array, array("Dummy\CustomSort", "cmp"));
        return $array;
    }
}

$robert = new Person(20);
$peter = new Person(12);
$robin = new Person(44);
$people = array($robert, $peter, $robin);

var_dump( $people );

$customSort = new CustomSort();
$people = $customSort->sortObjectArrayByField($people, 'age');

var_dump( $people );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接