PHP Sort функция для сортировки массива объектов - PullRequest
7 голосов
/ 20 сентября 2010

У меня есть массив объектов из того же класса.Я хотел бы отсортировать этот массив по необязательному объектному полю, например $case->ID или $case->Sender

. Есть ли встроенный вариант функции array_sort (), которая это делает, или мне придетсясам написать эту функцию сортировки?

Ответ не должен объяснять подробно - это больше похоже на вопрос да / нет

Спасибо


Моя неудачная попыткав usort:

function sortBy($sort)
  {
   usort($this->abuseCases, function($a, $b) {
     if($a->{$sort} > $b->{$sort}) return 1;
     if($a->{$sort} < $b->{$sort}) return -1;
     else return 0;
    });
  }

Еще одна неудачная попытка:

    function sortBy($sort)
    {
        $this->sortBy = $sort;

        usort($this->abuseCases, array("this", "srt"));
    }

    private function srt($a, $b)
    {
        if($a->{$this->sortBy} > $b->{$this->sortBy}) return 1;
        if($a->{$this->sortBy} < $b->{$this->sortBy}) return -1;
        else return 0;
    }

Правка для удара

Ответы [ 5 ]

10 голосов
/ 20 сентября 2010

Вы можете использовать не только анонимную функцию, но и замыкание, например,

function ($a,$b) use ($sort) { ... }

и $ sort будут доступны в теле функции. Автономный пример:

<?php
function getFn($sort) {
  return function($a, $b) use($sort) {
    if($a->$sort > $b->$sort) return 1;
    if($a->$sort < $b->$sort) return -1;
    return 0;
  };
}

$abuseCases = array(
  (object)array('ID'=>1, 'Sender'=>'Sender A'),
  (object)array('ID'=>3, 'Sender'=>'Sender D'),
  (object)array('ID'=>2, 'Sender'=>'Sender C'),
  (object)array('ID'=>4, 'Sender'=>'Sender B')
);

echo "\n----- Sort By Sender ----\n";
usort($abuseCases, getFn('Sender'));
foo($abuseCases);

echo "\n----- Sort By ID ----\n";
usort($abuseCases, getFn('ID'));
foo($abuseCases);

function foo($a) {
  foreach($a as $o) {
    echo $o->ID, ' ', $o->Sender, "\n";
  }
}

печать

----- Sort By Sender ----
1 Sender A
4 Sender B
2 Sender C
3 Sender D

----- Sort By ID ----
1 Sender A
2 Sender C
3 Sender D
4 Sender B

Обновление : При php <5.3 вы можете использовать объект вместо анонимной функции. usort () ожидает, что второй параметр будет <code>callable. Начиная с php 5.3 это может быть аномальная функция, но это также может быть имя функции .... или имя объекта и метода, передаваемые в виде массива, например array($obj, 'methodName').

$abuseCases = getData();
echo "\n----- Sort By Sender ----\n";
usort($abuseCases, array(new Foo('Sender'), 'compare'));
foo($abuseCases);

echo "\n----- Sort By ID ----\n";
usort($abuseCases, array(new Foo('ID'), 'compare'));
foo($abuseCases);

class Foo {
  public $propName; // protected?
  public function __construct($propertyName) {
    $this->propName = $propertyName;
  }
  public function compare($a, $b) {
    $prop = $this->propName;
    if($a->$prop > $b->$prop) return 1;
    if($a->$prop < $b->$prop) return -1;
    return 0;
  }
}

function foo($a) {
  foreach($a as $o) {
    echo $o->ID, ' ', $o->Sender, "\n";
  }
}
function getData() {
  return array(
    (object)array('ID'=>1, 'Sender'=>'Sender A'),
    (object)array('ID'=>3, 'Sender'=>'Sender D'),
    (object)array('ID'=>2, 'Sender'=>'Sender C'),
    (object)array('ID'=>4, 'Sender'=>'Sender B')
  );
}

(Если вы интенсивно используете это - или не хотите писать оправдания вроде этого -_- - вы можете захотеть определить интерфейс, такой как interface Comparator { ... }, позвольте Foo реализовать этот интерфейс и иметь некоторую функцию / класс который использует Comparator, то есть оболочку для объектов вокруг usort ().)

7 голосов
/ 20 сентября 2010

Вы можете использовать usort как:

function cmp( $a, $b ) {    
  return ($a->ID - $b->ID); // assuming numeric ID
} 

usort($arrayOfObjects,'cmp');

В PHP> = 5.3 вы также можете использовать анонимную функцию как:

usort($arrayOfObjects, function($a, $b) {
        return $a->ID - $b->ID;
    });
0 голосов
/ 20 сентября 2010

Из дизайна POV лучшим вариантом будет использование выделенного объекта (например, CasesCollection) вместо простых массивов. Вы можете сделать ключ сортировки членом этого объекта и тривиально ссылаться на него как $this->sortKey в обратном вызове сортировки.

0 голосов
/ 20 сентября 2010

Вы должны взглянуть на функцию usort ().Он принимает обратный вызов, который выполняет пользовательскую сортировку, что вам нужно.

0 голосов
/ 20 сентября 2010

Вам придется написать это, но это довольно тривиально с usort():

function my_obj_sort($a, $b) {
    return strnatcasecmp($a->Sender, $b->Sender);
}

usort($cases, 'my_obj_sort');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...