如何在PHP中对对象数组进行排序?

如何在PHP中对对象数组进行排序?,php,arrays,oop,sorting,Php,Arrays,Oop,Sorting,假设我有一群人,每个人都有名字、性别和年龄属性,编码如下: public class Person { private $name, $sex, $age; public function Person ($name, $sex, $age) { $this->name = $name; $this->sex = $sex; $this->age = $age; } public function getN

假设我有一群人,每个人都有名字、性别和年龄属性,编码如下:

public class Person
{
   private $name, $sex, $age;
   public function Person ($name, $sex, $age)
   {
       $this->name = $name;
       $this->sex = $sex;
       $this->age = $age;
   }
   public function getName();    
   public function getSex();
   public function getAge();
}

public class People
{
   private $people = array();
   public function addPerson ($name, $sex, $age)
   {
      $this->people[] = new Person($name, $sex, $age);
   }
}
class People {
    // your previously defined stuff here...

    public function sort() {
        usort($this->people, array($this, 'comparePeople'));
    }

    public function comparePeople(Person $p1, Person $p2) {
        return strcmp($p1->getName(), $p2->getName());
    }
}
function sortPeople($people) {
    usort($people, array('People', 'comparePeople'));
}

class People {
    // your previously defined stuff here...

    public static function comparePeople(Person $p1, Person $p2) {
        return strcmp($p1->getName(), $p2->getName());
    }
}
我如何实现一个方法
sortPeople()
,该方法将
$people
数组按人名的升序排序到
people
类中?

看一看。它允许您指定自己的比较函数。每次需要比较两个对象时,它都会调用您指定的比较函数,以查看哪一个大于另一个(或者它们是否相等)。在比较函数中,您可以对两个
Person
对象中的字段执行任何需要的操作,以进行比较

要使用类方法进行回调(如示例中所示),请参阅。例如,您可以这样做:

public class Person
{
   private $name, $sex, $age;
   public function Person ($name, $sex, $age)
   {
       $this->name = $name;
       $this->sex = $sex;
       $this->age = $age;
   }
   public function getName();    
   public function getSex();
   public function getAge();
}

public class People
{
   private $people = array();
   public function addPerson ($name, $sex, $age)
   {
      $this->people[] = new Person($name, $sex, $age);
   }
}
class People {
    // your previously defined stuff here...

    public function sort() {
        usort($this->people, array($this, 'comparePeople'));
    }

    public function comparePeople(Person $p1, Person $p2) {
        return strcmp($p1->getName(), $p2->getName());
    }
}
function sortPeople($people) {
    usort($people, array('People', 'comparePeople'));
}

class People {
    // your previously defined stuff here...

    public static function comparePeople(Person $p1, Person $p2) {
        return strcmp($p1->getName(), $p2->getName());
    }
}
当然,您还需要将
getName()
添加到
Person
类中

对于静态方法,它可能如下所示:

public class Person
{
   private $name, $sex, $age;
   public function Person ($name, $sex, $age)
   {
       $this->name = $name;
       $this->sex = $sex;
       $this->age = $age;
   }
   public function getName();    
   public function getSex();
   public function getAge();
}

public class People
{
   private $people = array();
   public function addPerson ($name, $sex, $age)
   {
      $this->people[] = new Person($name, $sex, $age);
   }
}
class People {
    // your previously defined stuff here...

    public function sort() {
        usort($this->people, array($this, 'comparePeople'));
    }

    public function comparePeople(Person $p1, Person $p2) {
        return strcmp($p1->getName(), $p2->getName());
    }
}
function sortPeople($people) {
    usort($people, array('People', 'comparePeople'));
}

class People {
    // your previously defined stuff here...

    public static function comparePeople(Person $p1, Person $p2) {
        return strcmp($p1->getName(), $p2->getName());
    }
}

正如你所看到的,它看起来非常相似。我不建议您使用静态方法。它比较混乱,违反了单一责任原则。

这里是一个使用静态方法的工作代码。它还使用了静态方法可以访问私有IVAR的事实:) 它还使用PHP可怕的自反性,特别是如果getName()是一个耗时的操作,那么使用装饰排序取消装饰模式可能会更好

<?php

class Person {
    private $name;
    function getName() {
      return $this->name;
    }
    function __construct($name) {
      $this->name = $name;
    }
}

$people = array(
    new Person('Jim'),
    new Person('Tom'),
    new Person('Tim'),
    new Person('Adam')
);

// actual sorting below
$people = array_map(create_function('$a', 'return array($a->getName(), $a);'), $people); // transform array of objects into array of arrays consisted of sort key and object
sort($people); // sort array of arrays
$people = array_map('end', $people); // take only last element from each array

print_r($people);
为什么这么快
这种方法可能比使用
usort
更快,因为对于长度为n的排序数组,它只调用getName()n次。排序期间的比较是使用内置比较器完成的,因此应该很快。在
usort
方法中,在排序过程中多次(超过n次)调用自定义比较器,它可能会减慢速度。

很有趣,但在包含类的文件中为此创建函数将非常难看。有没有办法传递像
People::comparePeople()
这样的函数,使排序函数是
People
类的一部分,而不是独立的函数?或者更好:
返回strcmp($p1->name,$p2->name);)@ClickUpvote:您可以通过People::comparePeople(您可能必须声明它是静态的)我正在编辑我的答案,以包括一个如何使用非静态的示例。好的,答案已编辑。还没有检查语法,但应该可以。诀窍是调用用户函数()相当难看。想要解释代码是如何工作的吗?解释是“不排序对象数组,而是排序数组,数组的最后一个元素是object,第一个元素是要排序的键。排序后,只保留对象。”我试图详细阐述这种排序的机制。如果您在理解上有进一步的困难,请通过询问具体问题让我知道。