如何在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,第一个元素是要排序的键。排序后,只保留对象。”我试图详细阐述这种排序的机制。如果您在理解上有进一步的困难,请通过询问具体问题让我知道。