2009-10-27 5 views
12

necesito algo como esto:Iterar Doctrina colección ordenada por algún campo

 $products = Products::getTable()->find(274); 
     foreach ($products->Categories->orderBy('title') as $category) 
     { 
      echo "{$category->title}<br />"; 
     } 

Sé que no es posible, pero ... ¿Cómo puedo hacer algo como esto sin crear una Doctrine_Query?

Gracias.

Respuesta

9

Solo estaba viendo el mismo problema. Es necesario para convertir el Doctrine_Collection en una matriz:

$someDbObject = Doctrine_Query::create()...; 
$children = $someDbObject->Children; 
$children = $children->getData(); // convert from Doctrine_Collection to array 

continuación, puede crear una función de ordenación y llamarlo:

// sort children 
usort($children, array(__CLASS__, 'compareChildren')); // fixed __CLASS__ 

Dónde compareChildren se ve algo como:

private static function compareChildren($a, $b) { 
    // in this case "label" is the name of the database column 
    return strcmp($a->label, $b->label); 
} 
+2

su solución sólo funcionaba cuando me cambié a: usort ($ hijos, array (_____ CLASS_____, 'compareChildren')); – stoefln

31

usted también puede hacer:

$this->hasMany('Category as Categories', array(... 
      'orderBy' => 'title ASC')); 

En el archivo de esquema que parece:

Relations: 
    Categories: 
     class: Category 
     .... 
     orderBy: title ASC 
+5

Si la clasificación es "permanente", usar esta forma es mucho mejor que utilizar la de Chris William. – avetisk

+2

El inconveniente es la permanencia. Agregar una ordenPor CADA consulta para esta relación tendrá un impacto en el rendimiento. –

+0

o mediante la anotación '@ OrderBy': http://docs.doctrine-project.org/en/2.0.x/reference/annotations-reference.html#annref-orderby – zizoujab

3

Es posible agregar una función de clasificación para Colletion.php:

public function sortBy($sortFunction) 
{ 
    usort($this->data, $sortFunction); 
} 

Ordenar una Doctrine_Collection de los usuarios por su edad se vería así:

class ExampleClass 
{ 

    public static function sortByAge($a , $b) 
    { 
     $age_a = $a->age; 
     $age_b = $b->age; 

     return $age_a == $age_b ? 0 : $age_a > $age_b ? 1 : - 1; 
    }  

    public function sortExample() 
    { 
     $users = User::getTable()->findAll(); 
     $users ->sortBy('ExampleClass::sortByAge'); 

     echo "Oldest User:"; 
     var_dump ($users->end()); 
    } 

} 
9

Se podría utilizar la colección iterador:

$collection = Table::getInstance()->findAll(); 

$iter = $collection->getIterator(); 
$iter->uasort(function($a, $b) { 
    $name_a = (int)$a->getName(); 
    $name_b = (int)$b->getName(); 

    return $name_a == $name_b ? 0 : $name_a > $name_b ? 1 : - 1; 
});   

foreach ($iter as $element) { 
    // ... Now you could iterate sorted collection 
} 

Si desea ordenar la colección utilizando el método __toString, será mucho más fácil:

foreach ($collection->getIterator()->asort() as $element) { /* ... */ } 
+1

Probado usando '$ collection-> getIterator() -> asort()' pero simplemente devuelve bool. –

+0

Lo siento, olvidé cómo funciona. Tienes razón, vuelve verdadero en el éxito y falso en el fracaso. Un diseño tan agradable. – temochka

+0

Lo más probable es que si llama a asort antes de iterar, podrá recorrer la lista ordenada. –

Cuestiones relacionadas