2010-03-19 17 views
80

Mam następujący structue tablicy:PHP Sortuj tablicę według SubArray Wartość

Array 
     (
      [0] => Array 
       (
        [configuration_id] => 10 
        [id] => 1 
        [optionNumber] => 3 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [1] => Array 
       (
        [configuration_id] => 9 
        [id] => 1 
        [optionNumber] => 2 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [2] => Array 
       (
        [configuration_id] => 8 
        [id] => 1 
        [optionNumber] => 1 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 
    ) 

Jaki jest najlepszy sposób, aby tablica, w sposób narastający na podstawie optionNumber?

Więc wyniki wyglądać następująco:

Array 
     (
      [0] => Array 
       (
        [configuration_id] => 8 
        [id] => 1 
        [optionNumber] => 1 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [1] => Array 
       (
        [configuration_id] => 9 
        [id] => 1 
        [optionNumber] => 2 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [2] => Array 
       (
        [configuration_id] => 10 
        [id] => 1 
        [optionNumber] => 3 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 
    ) 

Odpowiedz

152

Zastosowanie usort.

function cmp_by_optionNumber($a, $b) { 
    return $a["optionNumber"] - $b["optionNumber"]; 
} 

... 

usort($array, "cmp_by_optionNumber"); 

W PHP ≥5.3, należy użyć anonymous function zamiast:

usort($array, function ($a, $b) { 
    return $a['optionNumber'] - $b['optionNumber']; 
}); 

Należy zauważyć, że zarówno kod powyżej zakładają $a['optionNumber'] jest liczbą całkowitą. Użyj @St. John Johnson's solution, jeśli są to ciągi.


W PHP ≥7.0 użyj spaceship operator <=> Zamiast odejmowania uniknąć problemów przelewowy/przycinania.

usort($array, function ($a, $b) { 
    return $a['optionNumber'] <=> $b['optionNumber']; 
}); 
+1

To naprawdę nie helpe mnie jako usort wymaga zapewniam, że jest to funkcja w użyciu - co jest trudne nieco nie mogę uzyskać moja głowa okrągłe – Sjwdavies

+11

Studnia on właśnie dał ci funkcji używać. I będziesz musiał zaakceptować, że nie zawsze jest wbudowana funkcja do zrobienia tego, co chcesz, musisz napisać to sam. Funkcje porównania wymagają po prostu powrotu 1, 0 lub -1 wskazującego kolejność sortowania dla dwóch elementów. – Tesserex

+1

Spojrzałem dalej w usort i jest całkiem niezły. Napisałem prostą funkcję porównywania do powyższej, jednak pominąłem "==". Dzięki za pomoc faceci – Sjwdavies

48

Zastosowanie usort

usort($array, 'sortByOption'); 
function sortByOption($a, $b) { 
    return strcmp($a['optionNumber'], $b['optionNumber']); 
} 
+0

Ten pracował dla mnie. @ KennyTM nie wydawało się działać –

+7

@BenSinclair, to dlatego, że rozwiązanie Kenny'ego jest dla liczb, to rozwiązanie jest dla ciągów. Oba są poprawne :-) +1 dla tej alternatywy. – kubilay

+0

Pracowałem dla mnie, ponieważ sortowałem struny ... – Andy

4

Klucze są usuwane po użyciu funkcji, takich jak te powyżej. Jeśli klucze są ważne, poniższa funkcja zachowałaby je ... ale pętle foreach są dość nieefektywne.

function subval_sort($a,$subkey) { 
    foreach($a as $k=>$v) { 
     $b[$k] = strtolower($v[$subkey]); 
    } 
    asort($b); 
    foreach($b as $key=>$val) { 
     $c[$key] = $a[$key]; 
    } 
    return $c; 
} 
$array = subval_sort($array,'optionNumber'); 

Użyj arsort zamiast asort, jeśli chcesz od wysokiego do niskiego.

kredytowej

Kod: http://www.firsttube.com/read/sorting-a-multi-dimensional-array-with-php/

3

PHP 5.3+

usort($array, function($a,$b){ return $a['optionNumber']-$b['optionNumber'];}); 
11

Kiedyś oba rozwiązania przez KennyTM i AJ Quick i wpadł funkcji, które mogą pomóc w tej kwestii dla wielu przypadkach jak używając ASC lub DESC sortowanie lub zachowywanie kluczy lub jeśli masz obiekty jako dzieci z tablicy.

Oto ta funkcja:

/** 
* @param array $array 
* @param string $value 
* @param bool $asc - ASC (true) or DESC (false) sorting 
* @param bool $preserveKeys 
* @return array 
* */ 
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false) 
{ 
    if ($preserveKeys) { 
     $c = array(); 
     if (is_object(reset($array))) { 
      foreach ($array as $k => $v) { 
       $b[$k] = strtolower($v->$value); 
      } 
     } else { 
      foreach ($array as $k => $v) { 
       $b[$k] = strtolower($v[$value]); 
      } 
     } 
     $asc ? asort($b) : arsort($b); 
     foreach ($b as $k => $v) { 
      $c[$k] = $array[$k]; 
     } 
     $array = $c; 
    } else { 
     if (is_object(reset($array))) { 
      usort($array, function ($a, $b) use ($value, $asc) { 
       return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} - $b->{$value}) * ($asc ? 1 : -1); 
      }); 
     } else { 
      usort($array, function ($a, $b) use ($value, $asc) { 
       return $a[$value] == $b[$value] ? 0 : ($a[$value] - $b[$value]) * ($asc ? 1 : -1); 
      }); 
     } 
    } 

    return $array; 
} 

Zastosowanie:

sortBySubValue($array, 'optionNumber', true, false); 

Edit

Pierwsza część może być zapisane w uasort() i functi na będzie krótszy:

/** 
* @param array $array 
* @param string $value 
* @param bool $asc - ASC (true) or DESC (false) sorting 
* @param bool $preserveKeys 
* @return array 
* */ 
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false) 
{ 
    if (is_object(reset($array))) { 
     $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) { 
      return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} - $b->{$value}) * ($asc ? 1 : -1); 
     }) : usort($array, function ($a, $b) use ($value, $asc) { 
      return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} - $b->{$value}) * ($asc ? 1 : -1); 
     }); 
    } else { 
     $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) { 
      return $a[$value] == $b[$value] ? 0 : ($a[$value] - $b[$value]) * ($asc ? 1 : -1); 
     }) : usort($array, function ($a, $b) use ($value, $asc) { 
      return $a[$value] == $b[$value] ? 0 : ($a[$value] - $b[$value]) * ($asc ? 1 : -1); 
     }); 
    } 
    return $array; 
} 
+0

To jest najlepsza najbardziej przydatna odpowiedź tutaj, powinna być na górze;) –

+0

@EdiBudimilic dziękuję, doceniam to! Przy okazji zaktualizowałem swoją odpowiedź i dodałem krótszą wersję tej funkcji :) –

+1

Aby to działało, musiałem użyć '>' (większy niż) zamiast '-' (minus) podczas porównywania' $ wartości a' i '$ b', ponieważ porównywałem łańcuchy. Wciąż działa. – James

Powiązane problemy