2012-06-16 15 views
10

Rozważmy następujący asocjacyjnamulti-rodzaj tablicy asocjacyjnej w PHP

$arr = Array 
(  
    [banana] => 2 
    [cherry] => 1 
    [orange] => 3 
    [grapefruit] => 1 
    [apple] => 1 
) 

chcę rozwiązać to w sposób, który byłby podobny do terminu PLSQL: A DESC, B ASC (gdzie A jest wartość i B jest kluczem) znaczenie:

$arr = Array 
(
    [orange] => 3 
    [banana] => 2 
    [apple] => 1 
    [cherry] => 1 
    [grapefruit] => 1   
) 

tak, pomarańczy i bananów są pierwsze ze względu na wartość, ale potem mam jabłko, wiśnia i grejpfruta w kolejności alfabetycznej, ponieważ mają tę samą wartość.

Co próbowałem:
1. uruchomić ksort() a następnie asort()/rsort() nadzieję, że drugi rodzaj będzie wpadać na pomarańczowo i banan na początku tablicy, nie brudząc się sortowania alfabetycznego pozostałych 3 pozycji . Myliłem się. to wszystko miesza. Więc sprawdziłem:
2. sort functions i array_multisort(). Ale najwyraźniej sortuje kilka tablic na raz lub tablicę wielowymiarową.
3. Próbowałem też zdefiniować następujące porównanie funkcji:

function cmp($a, $b) 
{ 
    foreach ($a as $key1 => $val1) { 
     foreach ($b as $key2 => $val2) { 
      if($val1 == $val2){ 
       return strcmp($key1,$key2); 
      } 
      else if ($val1 > $val2){ 
       return 1; 
      } 
      else{ // $val1 < $val2 
       return -1; 
      } 
     } 
    }  
} 

i nazywają go usort() ale to również nie działa.

Moje pytanie brzmi: czy istnieje metoda PHP, która implementuje żądane zachowanie?

Eugen:
Próbowałem i nie działa przed sortowaniem:

Array 
(
    [lamb] => 3 
    [rule] => 1 
    [children] => 1 
    [teacher] => 2 
    [eager] => 1 
) 

i po sortowaniu:

Array 
(
    [children] => 1 
    [eager] => 1 
    [rule] => 1 
    [teacher] => 2 
    [lamb] => 3 
) 
+0

Jak będzie używana wynikowy tablicę? – Galen

+0

@ Galena w bardzo wyrafinowany i potężny sposób, którego nigdy nie widziano na Ziemi;) – alfasin

+1

Jeśli chodzi o pierwsze podejście, nie działało, ponieważ sortowanie PHP nie jest stabilne (tj. Zachowuje porządek na równych wartościach). – Sarke

Odpowiedz

12

Można użyć array_multisort

<?php 
    $arr = Array 
    (  
     'banana' => 2, 
     'cherry' => 1, 
     'orange' => 3, 
     'grapefruit' => 1, 
     'apple' => 1 
    ); 

    $values = array_values($arr); 
    $keys = array_keys($arr); 

    //first sort by values desc, then sort by keys asc 
    array_multisort($values, SORT_DESC, $keys, SORT_ASC, $arr); 

    print_r($arr); 
    // output: 
    /* 
    Array 
    (
     [orange] => 3 
     [banana] => 2 
     [apple] => 1 
     [cherry] => 1 
     [grapefruit] => 1 
    ) 
    */ 

?> 

To działa tak:

  • dla każdej kolumny używanej do sortowania (wartości i klucze dla ciebie), tworzyć nowe 1d tablicę z jego treścią
  • przekazać te 1d tablic do funkcji array_multisort w sortowaniu zamówienie ($ więc wartości, potem $ klucze), dodać porządek na każdej tablicy
  • ostatni argument musi być tablicę której chcesz sortować

(być może znajdziesz this explanation łatwiej zrozumieć)

+0

Nie wiem, dlaczego dostałeś -1, dostałeś +1 ode mnie, ponieważ twoje rozwiązanie rzeczywiście działa, dzięki! – alfasin

+2

@alfasin dziękuje :), ludzie są tak szybcy w downvotingu i nie wyjaśniają dlaczego ... – Zbigniew

+0

Jeśli chcemy dodać wiele flag Sortowania dla każdego elementu, który chcemy posortować, czy to zadziała? –

3
function polysortcmp($a, $b) { 
    if ($a[1]<$b[1]) return 1; 
    if ($a[1]>$b[1]) return -1; 
    if ($a[0]<$b[0]) return -1; 
    if ($a[0]>$b[0]) return 1; 
    return 0; 
} 


function polysort(&$arr) { 
    foreach ($arr as $k=>$v) $arr[$k]=array($k,$v); 
    uasort($arr, "polysortcmp"); 
    foreach ($arr as $k=>$v) $arr[$k]=$v[1]; 
} 
+0

to nie działa. Aktualizuję pytanie, aby pokazać, jaki jest wynik, jeśli spróbuję go po swojemu. – alfasin

+0

Przepraszam, błędnie Cię odczytałem: Najpierw posortowałem według klucza, potem wartość - zaktualizowałem moją odpowiedź. –

+0

Teraz sortuje alfabetycznie, ale WARTOŚCI są w kolejności ASC zamiast DESC. Zaktualizowałem moje pytanie, aby pokazać aktualny wynik twojego kodu. Możesz wziąć przykład, który dałem i go uruchomić. – alfasin

0

tablica funkcja sortowania arsort wykorzystywane ..

$arr = array(  
     'banana' => 2, 
     'cherry' => 1, 
     'orange' => 3, 
     'grapefruit' => 1, 
     'apple' => 1 
    ); 

arsort($arr); 
print_r($arr); 

Wyjście

Array ([orange] => 3 [banana] => 2 [apple] => 1 [grapefruit] => 1 [cherry] => 1) 
+0

Próbowałem arsort() i to nie działa. może działać na tym konkretnym przykładzie, który podałem - ale nie zadziała w ogólnym przypadku. – alfasin

Powiązane problemy