Z notatnika webmasterki

02 Gru, 2012

Sortowanie stringów z polskimi znakami

Zamieszczony przez: Joanna w: PHP

Stanęłam ostatnio przed zadaniem posortowanie tablicy zawierającej nazwy miejscowości. Nazwy pobierane były z bazy i zapisane w utf-8. Ani sortowanie w zapytaniu ani standardowe funkcje sortujące dostępne w php nie robiły tego prawidłowo.

Postanowiłam więc sięgnąć po funkcję usort() i zdefiniować własną, jak sądzę, bardzo sprytną funkcję porównującą, która rozwiązała mój problem. Jak wiadomo taka funkcja przyjmuje dwa parametry tj dwie wartości do porównania i musi zdecydować czy są one w poprawnej kolejności czy nie. Poniżej kod funkcji porównującej i objaśnienie:

function sort_m($a, $b){
	$search = array('ę','ó','ą','ś','Ś','ł','Ł','ż','Ż','ź','Ź','ń','Ń');
	$replace = array('ezz','ozz','azz','szz','Szz','lzz','Lzz','zz_','Zz_',
		'zzz','Zzz','nzz','Nzz');
	$a = str_replace($search, $replace,$a);
	$b = str_replace($search, $replace,$b);
	$arrTmp = array($a,$b);
	sort($arrTmp);
	return ($a == $arrTmp[0])? -1:1;
}

Najpierw zdefiniowałam sobie tablice polskich znaków, które mnie interesują (pominęłam kilka wielkich, gdyż nie ma miast na przykład na literę Ą.
Następnie zdefiniowałam listę zamienników. Ponieważ chcę, żeby znak ‚ą’ ustawiał się za ‚a’ zamieniam go na ‚azz’. W ten sposób mam pewność, że stringi ‚kaz’ i ‚kąc’ ustawią się we właściwej kolejności, bo ten drugi zostanie zamieniony (do celów porównania) na ‚kazzc’. W przypadku znaków ‚ź’ i ‚ż’ zastosowałam nieco inne stringi, żeby zapewnić sobie odpowiednie sortowanie tych znaków względem siebie.
Następnie tak zmienione stringi wrzucam do dwuelementowej tablicy i sortuję. Jeśli kolejność nie została zmieniona funkcja porównująca zwraca wartość ujemną w przeciwnym razie wartość dodatnią. I już.

10 komentarzy na "Sortowanie stringów z polskimi znakami"

1 | cap0ne

3. grudnia 2012 o 9:25 am

Avatar

A ustawienie COLLATE w mysql nie załatwiłoby sprawy, np:

SELECT * FROM `wojewodztwa` WHERE 1 ORDER BY `nazwa` COLLATE utf8_polish_ci

2 | Joanna

3. grudnia 2012 o 12:24 pm

Avatar

Niestety nie. Uporczywie ‚Ś’ lokuje się między ‚L’ a ‚M’ zaś ‚Ł’ międzu ‚K’ a ‚L’.

3 | seara.pl76

28. grudnia 2012 o 9:06 pm

Avatar

Bardzo fajny wpis. Dużo się dowiedziałem. Trzeba będzie przejżeć całą stronę :-)
Pozdrawiam i zapraszam na moją stronę.

4 | MythThrazz

23. września 2013 o 10:05 am

Avatar

Sprytnie, bardzo sprytnie. Brakuje co prawda kilku znaków, ale generalna zasada genialna.

5 | rebelthorn

11. grudnia 2013 o 12:17 pm

Avatar

hmm to jak ciosanie kamienia innym kamieniem żeby wyszło koło ;) ..
COLLATE w mysql spokojnie listuje PL ogonki POD WARUNKIEM, że tablica ustawiona jest na utf8_polish_ci
Pozdrawiam

6 | Joanna

1. lutego 2014 o 3:36 pm

Avatar

Mam wrażenie, że nie przeczytałeś wszystkiego uważnie. A to nie dobrze, bo uważne czytanie ze zrozumieniem to cnota wielce pożądana u programistów :)

7 | antek

4. stycznia 2014 o 3:39 pm

Avatar

No nie wiem, czy w tej Świecko (==Szzwiecko ) nie będzie później niż Szydłowiec?

8 | Joanna

1. lutego 2014 o 3:35 pm

Avatar

A nie powinno być później?

9 | kermit

8. maja 2014 o 1:51 pm

Avatar

@rebelthorn: dzięki! uratowałeś mi godzin szukania.

10 | Daniel Wolak

11. czerwca 2014 o 4:18 pm

Avatar

Witam
Męczę się z tym samym problemem od momentu przekonwertowania bazy z iso do utf8. Wszystko co zaczyna się na Ł, Ż, Ź czy Ś wrzuca po L i czego bym nie spróbował zawsze źle. Baza jest ustawiona na uft8_polish, metoda porównywania też. Gdybym wrzucał przez phpmyadmin, to problemu by nie było, ale używając własnego CMS mam Ĺťywioły zamiast Żywioły… Czy twoja funkcja to jedyne wyjście? UTF8 miało pomagać…

Formularz komentarza

Wrzesień 2017
P W Ś C P S N
« Lip    
 123
45678910
11121314151617
18192021222324
252627282930  

Archiwa

About

Moje notatki z pracy

Subskrypcja

Wprowadź swój adres email aby zaprenumerować ten blog i otrzymywać powiadomienia o nowych wpisach przez email.

Dołącz do 24 pozostałych subskrybentów

Tematy