2016-05-09 2 views
1

J'essaye de trier mon tableau d'objets basé sur SUM minimal. Ceci fonctionne, mais je veux ajouter à ma fonction d'usort une autre comparaison, qui préférera l'objet, qui aura une valeur vraie. Mes objets:Objet de tri PHP avec usort basé sur deux valeurs

object(Basket)[33] 
     public 'products' => 
     array (size=2) 
      0 => 
      object(Product)[13] 
       public 'name' => string 'Name ONE' (length=8) 
       public 'price' => float 0.75 
       public 'exist' => boolean true 
      1 => 
      object(Product)[7] 
       public 'name' => string 'Name TWO' (length=8) 
       public 'price' => float 2.39 
       public 'exist' => boolean true 
     public 'sum' => float 3.14 

object(Basket)[34] 
     public 'products' => 
     array (size=2) 
      0 => 
      object(Product)[19] 
       public 'name' => string 'Name ONE' (length=8) 
       public 'price' => float 0.75 
       public 'exist' => boolean true 
      1 => 
      object(Product)[72] 
       public 'name' => string 'Name TWO' (length=8) 
       public 'price' => null 
       public 'exist' => boolean false 
     public 'sum' => float 0.75 

object(Basket)[35] 
     public 'products' => 
     array (size=2) 
      0 => 
      object(Product)[1] 
       public 'name' => string 'Name ONE' (length=8) 
       public 'price' => float 0.75 
       public 'exist' => boolean true 
      1 => 
      object(Product)[2] 
       public 'name' => string 'Name TWO' (length=8) 
       public 'price' => float 1.75 
       public 'exist' => boolean true 
     public 'sum' => float 2.5 

Et si je sort cela, l'ordre est Basket[34],Basket[35],Basket[33]. Mais je veux Basket[35],Basket[33] et à la fin Basket[34], parce qu'il a 1 produit, qui n'existe pas.

Donc je veux commander en fonction de l'existence du produit, puis sort par SUM. je, mais cela ne fonctionne pas:

usort($h_basket[$i], function($a, $b) { 
    return $a->sum > $b->sum; 
}); 
usort($h_basket[$i], function($a, $b) { 
    $unfinded_a = 0; 
    $unfinded_b = 0; 
    foreach ($a->products as $product) { 
    if(!$product->exist) { 
     $unfinded_a++; 
    } 
    } 
    foreach ($b->products as $product) { 
    if(!$product->exist) { 
     $unfinded_b++; 
    } 
    } 
    if ($unfinded_a != 0 || $unfinded_b != 0) 
    return $unfinded_b > $unfinded_a; 
}); 

est possible de le faire avec usort, ou je dois utiliser array_multisort?

Répondre

0

Pour trier par le « existe » champ (et je suppose que le plus grand pourcentage de tous un des produits charrettes qui existent, plus elles doivent être triées)

Je vous suggère d'utiliser array_filter pour obtenir un compte simple combien de produits ont «existe» par rapport au total

$exists = count(
    array_filter(
     $object->products, 
     function ($product) { 
      return $product->exist; 
     } 
    ) 
)/count($object->products); 

Ensuite, comparez la valeur $exists calculée pour les deux paniers étant comparés.

Pour trier par plusieurs champs (existe, et somme) je crois que vous aurez besoin d'appeler usort deux fois, en inverse ordre - Tri sum premier puis par exists

+0

Merci pour votre réponse, mais Je ne me démonte pas bien. Cela ne fonctionne pas: usort ($ h_basket [$ i], fonction ($ a, $ b) {return $ a-> somme> $ b-> somme;}); usort (de h_basket de $ [$ i], la fonction ($ a, $ b) { $ exists = count ( array_filter ( $ a-> produits, fonction (produit de $) { retour par produit de $> existe; } ) )/count ($ a-> produits); $ exists2 = nombre ( array_filter ( $ b-> produits, fonction (produit $) { retour par produit de $> existe; } )/count ($ b-> produits); return $ exists2> $ existe; }); – Michal