2010-09-20 15 views
7

Ich habe ein Array voller Objekte aus der gleichen Klasse. Ich möchte dieses Array von optionalen Objektfeld sortieren, zum Beispiel $case->ID oder $case->SenderPHP Sortierfunktion zum Sortieren eines Arrays von Objekten

Gibt es einen eingebauten Geschmack der array_sort() Funktion, die dies bereits der Fall ist, oder muss ich diese Art zu schreiben, mich funktionieren?

Antwort muss nicht im Detail erklären - das ist mehr wie ein ja/nein Frage

Dank


Mein gescheiterter Versuch bei 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; 
    }); 
    } 

Ein weiterer fehlgeschlagener Versuch:

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; 
    } 

Edit für Bump

+0

Warum scheitert es? Welches Ergebnis sehen Sie? – codaddict

+0

Im ersten Versuch wurde $ sort offensichtlich nicht gefunden. Im zweiten Versuch weiß ich nicht, wie ich auf die Funktion 'srt' verweisen soll. – Hubro

Antwort

10

Sie können nicht nur eine anonyme Funktion, sondern eine Schließung verwenden, wie z.

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

und $ sort wird im Funktionskörper verfügbar sein. Autarke Beispiel:

<?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"; 
    } 
} 

druckt

----- 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 

aktualisieren: Mit PHP < 5.3 Sie ein Objekt statt einer anonymen Funktion verwenden können. usort() erwartet, dass der zweite Parameter ein callable ist. Das kann eine anoymous Funktion wie von PHP 5.3 sein, aber es kann auch der Name einer Funktion sein .... oder ein Objekt und ein Methodenname, der als ein Array wie array($obj, 'methodName') übergeben wird.

$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') 
); 
} 

(Wenn Sie schweren Gebrauch machen - oder wollen nicht Ausreden wie diese schreiben -_- - Sie könnten eine Schnittstelle wie interface Comparator { ... }, lassen Foo diese Schnittstelle implementieren und eine Funktion haben definieren wollen/Klasse, die Komparator verwendet, dh einen Wrapper für Objekte um usort().)

+2

Ein gutes Beispiel für die Verwendung von Schließungen. Funktioniert nur mit PHP 5.3 + – Iacopo

+0

Funktioniert perfekt. Vielen Dank! Wenn es eine Version des gleichen Ergebnisses gibt, die weniger Code benötigt, würde ich das auch gerne sehen: P – Hubro

+0

Entschuldigung, PHP 5.3 wird nicht verfügbar sein - Ich brauche eine andere Lösung – Hubro

7

Sie usort als verwenden können:

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

usort($arrayOfObjects,'cmp'); 

IN PHP> = 5.3 Sie auch anonyme Funktion als verwenden können:

usort($arrayOfObjects, function($a, $b) { 
     return $a->ID - $b->ID; 
    }); 
+0

Danke für die Antwort. Kennen Sie irgendwelche Methoden, um eine vordefinierte Variable in diese Sortierfunktion zu bekommen? Mein Versuch ist gescheitert (Ich habe ihn in den Hauptbeitrag geschrieben) – Hubro

0

Sie haben um es zu schreiben, aber es ist ziemlich trivial mit usort():

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

usort($cases, 'my_obj_sort'); 
0

Sie sollten sich die Funktion usort() ansehen. Es akzeptiert einen Rückruf, der benutzerdefinierte Sortierung durchführt, was Sie möchten.

0

Aus dem Entwurfs-POV wäre eine bessere Option, ein dediziertes Objekt (wie CasesCollection) anstelle von einfachen Arrays zu verwenden. Sie könnten den Sortierschlüssel zu einem Mitglied dieses Objekts machen und ihn im Sortierrückruf als $this->sortKey bezeichnen.

Verwandte Themen