Sortowanie tablic

PHP wyposaża nas w sumie w dwanaście funkcji, których zadaniem jest sortowanie tablic na przeróżne sposoby. Funkcje te to: sort(), asort(), rsort(), arsort(), ksort(), krsort(), natsort(), natcasesort(), usort(), uasort(), uksort() oraz array_multisort().

sort()

Do zwykłego sortowania używamy funkcji sort(). Jest to najbardziej podstawowa funkcja. Sortuje ona elementy od najmniejszego do największego bez zachowania kluczy.
bool sort (array &$array [, int $sort_flags = SORT_REGULAR])
Jako drugi, opcjonalny parametr funkcja ta przyjmuje liczbę determinującą sposób sortowania. Domyślnie jest to SORT_REGULAR, co oznacza, że podczas sortowania wartości nie są rzutowane. Możemy również przekazać jako drugi parametr SORT_NUMERIC – wówczas wartości będą rzutowane na typ numeryczny, a następnie sortowane. Trzecią opcją jest SORT_STRING – podobnie jak w poprzednim przypadku z tą różnicą, że wartości będą rzutowane do strignów. Istnieje jeszcze czwarta predefiniowana stała, którą możemy tu podać, jest to SORT_LOCALE_STRING. Jeśli ją podamy, wartości będą porównywane jak stringi w zależności od bieżącej lokalizacji. Funkcja ta zwraca TRUE w przypadku powodzenia, lub FALSE w przeciwnym wypadku. Warto zauważyć, że tablica do funkcji przekazywana jest przez referencję, dlatego funkcja ta operuje bezpośrednio na tablicy, nie na jej kopii. Druga rzecz to fakt, że sort() „gubi” klucze jakie znajdowały się w tablicy przed sortowaniem, a posortowanym elementom przypisuje nowe, numeryczne klucze poczynając od zera. Jeśli chcemy uzyskać efekt sortowania podobny do sort() z tą różnicą, że klucze mają być zachowane, powinniśmy użyć asort()

asort()

bool asort (array &$array [, int $sort_flags = SORT_REGULAR])
Funkcja ta zachowuje się niemalże identycznie jak sort(), z tą tylko różnicą, że zachowuje porządek kluczy z przed sortowania.

rsort()

bool rsort (array &$array [, int $sort_flags = SORT_REGULAR])
Ponownie kolejna wariacja funkcji sort() – tym razem odmiana, która sortuje elementy w porządku malejącym (od największego do najmniejszego). Ale podobnie jak sort() nie zachowuje kluczy.

arsort()

bool rsort (array &$array [, int $sort_flags = SORT_REGULAR])
Funkcja bardzo podobna do powyższej – sortuje elementy w porządku malejącym, z tą różnicą, że zachowuje klucze z przed sortowania.

natsort()

Podczas gdy wyżej wymienione funkcje sortują tablice poprzez porównywanie wartości numerycznych, lub przeprowadzają porównywanie bajt po bajcie w przypadku stringów, czasem potrzebujemy bardziej „naturalnego” rodzaju sortowania. Załóżmy że mamy taką tablicę:
$array = array('image1.png', 'image12.png', 'image5.png', 'image10.png');
Używając funkcji sort() do jej posortowania dostalibyśmy elementy w następującym porządku: image1.png, image10.png, image12.png, image5.png Logiczne jest jednak, że chcielibyśmy otrzymać coś takiego: image1.png, image5.png, image10.png, image12.png Da się to uzyskać dzięki zastosowaniu funkcji natsort():
bool natsort (array &$array)
Funkcja ta sortuje tablicę w sposób „naturalny” dla człowieka. Dodatkowo należy zapamiętać, że funkcja natsort() zachowuje oryginalne klucze z przed sortowania! Istnieje jednak kilka pułapek związanych ze stosowaniem natsort(): 1. Liczby ujemne
$negative = array('-5','3','-2','0','-1000','9','1');
echo 'Przed:<br>';
print_r($negative);
natsort($negative);
echo 'Po:<br>';
print_r($negative);
Ten kod wyświetli nam:
Przed:
Array
(
    [0] => -5
    [1] => 3
    [2] => -2
    [3] => 0
    [4] => -1000
    [5] => 9
    [6] => 1
)

Po:
Array
(
    [2] => -2
    [0] => -5
    [4] => -1000
    [3] => 0
    [6] => 1
    [1] => 3
    [5] => 9
)
2. Liczby dopełnione zerem
echo "Dopełnienie zerem\n";
$zeros = array('09', '8', '10', '009', '011', '0'); 
print_r($zeros);
natsort($zeros);
print_r($zeros);
Kod wyświetli:
Dopełnienie zerem
Array
(
    [0] => 09
    [1] => 8
    [2] => 10
    [3] => 009
    [4] => 011
    [5] => 0
)
Array
(
    [5] => 0
    [1] => 8
    [3] => 009
    [0] => 09
    [2] => 10
    [4] => 011
)
Jeszcze jedna ważna rzecz – natsort() rozróżnia wielkość liter. Generalnie jeśli mamy np. takie elementy: ‘abc’, ‘def’, ‘Ghi’, ‘jkl’, ‘Mno’, to wynikiem sortowania będzie: ‘Ghi’, ‘Mno’, ‘abc’, ‘def’, ‘jkl’ Czyli jak widać, funkcja najpierw bierze wszyskie wyrazy zaczynające się od dużych liter, sortuje je i wrzuca na początek tablicy, a później zajmuje się pozostałymi. Jeżeli chcemy, posortować elementy tablicy za pomocą algorytmu, z którego korzysta natsort(), ale przy tym chcemy, aby wielkość liter NIE była rozróżniana, powinniśmy użyć funkcji natcasesort().

natcasesort()

bool natcasesort (array &$array)
Sortuje tablicę w niemalże identyczny sposób co natsort() z tą różnicą, że podczas sortowania NIE jest rozróżniana wielkość liter.

ksort()

bool ksort (array &$array [, int $sort_flags = SORT_REGULAR])
Funkcja ksort() sortuje tablicę w inny sposób niż poprzenio wymienione funkcje. Porównuje ona bowiem klucze, nie wartości. Cała reszta (tzn. działanie opcjonalnego atrybutu $sort_flags, sama zasada porównywania kluczy) jest analogiczna do sort(), z tą jeszcze różnicą, że zachowane są klucze (co jest w tym przypadku logiczne, bo przecież po nich sortujemy).

krsort()

bool ksort (array &$array [, int $sort_flags = SORT_REGULAR])
Działa analogicznie do rsort() z tym że podobnie jak ksort() sortuje tablicę po kluczach, nie po wartościach. Elementy układane są od największego do najmniejszego.

usort()

PHP umożliwia nam również sortowanie tablicy za pomocą funkcji zdefiniowanej przez użytkownika. Służy do tego funkcja usort().
bool usort (array &$array, callback $cmp_function)
Oto przykład w jaki sposób działa usort():
function myCmp($left, $right)
{
	$diff = strlen($left) - strlen($right);
 
	if(!$diff)
		return 0;
	else
		return $diff;
}
 
$a = array('2baz', 'foo', 'betty', 'sally', 'new york');
usort($a, 'myCmp');
 
print_r($a);
Powyższa funkcja sortuje wyrazy z tablicy $a od najkrótszego do najdłuższego. Nasza funkcja myCmp() musi zwrócić zero w przypadku gdy oba elementy tablicy mają być traktowane jako równe, wartość mniejszą od zera, jeśli element po lewej jest większy od tego po prawej i wartość większą od zera w przeciwnym wypadku. Jak widać funkcja usort() analogicznie do sort() nie zachowuje kluczy z przed sortowania, tylko numeruje tablicę od nowa. Aby temu zapobiec należy użyć funkcji uasort().

uasort()

bool uasort (array &$array, callback $cmp_function)
Funkcja ta działa analogicznie do usort() z tą różnicą, że zachowuje ona klucze obecne w tablicy przed sortowaniem.

uksort()

Kolejna funkcja służąca do sortowania w „niecodzienny” sposób, która również działa analogicznie do przedstawionej wyżej usort(), tyle że ta porównuje ze sobą klucze tablicy, a nie jej wartości i na podstawie tego porównania układa elementy tablicy. Reszta odbywa się tak samo jak w przypadku usort().

array_multisort()

Na koniec mamy ciekawą funkcję służącą do sortowania kilku tablic na raz, lub do sortowania tablicy wielowymiarowej po więcej niż jednym wymiarze.
bool array_multisort (&$array [, mixed $arg = SORT_ASC [, mixed $arg = SORT_REGULAR [, mixed $... ]]])
Sposób sortowania array_multisort() można porównać w pewnym sensie do ORDER BY z SQL-a. Generalnie funkcja ta jako pierwszy argument przyjmuje tablicę, będąca tablicą nadrzędna – na jej podstawie będą sortowane także elementy innych tablic, które przekażemy do funkcji. Jeśli elementy tablicy pierwszej są równe, wówczas odpowiadające im elementy w drugiej tablicy będą porównywane. Brzmi to co najmniej zagmatwanie, ale jak zwykle wszystko rozjaśni przykład:
$ar1 = array(10, 100, 100, 0);
$ar2 = array(1, 3, 2, 4);
 
array_multisort($ar1, $ar2);
Po wykonaniu tego kodu, powyższe tablice będą miały następującą strukturę:
Array
(
    [0] => 0
    [1] => 10
    [2] => 100
    [3] => 100
)

Array
(
    [0] => 4
    [1] => 1
    [2] => 2
    [3] => 3
)
O ile wygląd pierwszej nie jest zaskakujący, o tyle układ elementów drugiej tablicy może na pierwszy rzut oka nieco dziwić. Jest to jednak to, o co nam chodziło. Przyjrzyjmy się uważniej. W pierwszej tablicy ostatni element poszedł na sam początek, ten który był na początku, poszedł na drugie miejsce, a na końcu mamy 100 i 100 – czyli o to chodziło, tablica jest posortowana. I teraz zauważ, że odpowiadające tym elementom elementy z drugiej tablicy „powędrowały” za nimi. Przed sortowaniem „4″ było na końcu, teraz jest na początku – czyli tak jak w przypadku pierwszej tablicy – „0″ było na końcu, teraz jest na początku. Tak samo ułożyły się pozostałe elementy. Zauważ też, że „2″ i „3″ odpowiadające „100″ też zostały posortowane. Funkcję array_multisort() można również wywołać w „bardziej skomplikowany” sposób, tzn. przekazać bardziej szczegółowe wytyczne co do sortowania. Załóżmy, że chcemy powyższe dwie tablice posortować w taki sposób: pierwszą rosnąco, przy czym jej elementy mają być traktowane stricte jak elementy numeryczne, natomiast druga ma być sortowana względem pierwszej malejąco, a jej elementy mają być traktowane jak stringi.
$ar1 = array(10, 100, 100, 0);
$ar2 = array(1, 3, 2, 4);
 
array_multisort($ar1, SORT_ASC, SORT_NUMERIC,
		     $ar2, SORT_DESC, SORT_STRING);
Po sortowaniu tablice będą miały postać:
Array
(
    [0] => 0
    [1] => 10
    [2] => 100
    [3] => 100
)

Array
(
    [0] => 4
    [1] => 1
    [2] => 3
    [3] => 2
)
Warto jeszcze zapamiętać, że array_multisort() zachowuje klucze asocjacyjne, ale gubi klucze numeryczne.

, ,

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

*

Możesz użyć następujących tagów oraz atrybutów HTML-a: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">