2016-05-09 3 views
1

Я пытаюсь сортировать массив объектов на основе минимального SUM. Это работает, но я хочу добавить к моей функции usort другое сравнение, которое предпочтет объект, который будет иметь одно значение true. Мои объекты:Объект сортировки PHP с usort на основе двух значений

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 

И если я sort это, порядок Basket[34],Basket[35],Basket[33].

Но я хочу Basket[35],Basket[33] и в конце Basket[34], потому что у него есть 1 продукт, которого не существует.

Поэтому я хочу заказать из базы данных на основе продукта, а затем sort от SUM. у меня есть, но это не работает:

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

Есть возможность сделать это с usort, или я должен использовать array_multisort?

ответ

0

Для сортировки по «существует» поле (и я полагаю, большую долю всего, тележки продуктов, которые существуют, тем выше он должен быть отсортирован)

Я хотел бы предложить вам использовать array_filter, чтобы получить простой подсчет сколько продуктов существует «существует» против общего количества, например

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

Затем сравните рассчитанное $exists значения для двух корзин сравниваемый.

Для сортировки по нескольким полям (существует, и тогда сумма) Я считаю, что вам нужно позвонить usort дважды, в обратном порядке - сортировать по sum первым затем по exists

+0

Спасибо за ваш ответ, но Я не плохо и хорошо. Это не работает: usort ($ h_basket [$ i], function ($ a, $ b) {return $ a-> sum> $ b-> sum;}); usort ($ h_basket [$ я], функция ($ а, $ б) { $ существует = Count ( array_filter ( $ a-> продукты, функцию ($ продукта) { возврата $ продукт-> существуют; } ) )/счетчик ($ a-> продукты); $ exists2 = счетчик ( array_filter ( $ b-> продукты, функция ($ продукта) { возврата $ продукт-> существуют; } ) )/count ($ b-> products); return $ exists2> $ exists; }); – Michal