note 50584 deleted from function.usort by danbrown
| From: | danbrown@php.net | Date: | Sun, 23 Jan 2011 16:29:22 +0000 |
| Subject: | note 50584 deleted from function.usort by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-176076@lists.php.net to get a copy of this message | ||
Note Submitter: ulrichUNDERSCOREalexis at yahoo dot com
----
<?php
/* returns the collated string (with no accent or with the matching string
* replacement) in lower case according to that language rule.
* The aim is to alphabetically sort lists of strings with characters from
* other languages but using collation rules of that given language
* (ISO 639-1 code).
* Latin-derived alphabets are supported (currently English, French and
* German)
* rules source: http://en.wikipedia.org/wiki/Latin_alphabet
*/
function collatedLower($string, $lang=null) {
switch ($lang) {
case 'de':
// German
/*
* In German, letters with umlaut (Ä, Ö, Ü) are treated generally
* just like their non-umlauted versions; ß is always sorted as ss.
* This makes the alphabetic order Arg, Ärgerlich, Arm, Assistent,
* Aßlar, Assoziation.
* For phone directories and similar lists of names, the umlauts are
* to be collated like the letter combinations "ae", "oe", "ue".
* This makes the alphabetic order Udet, Übelacker, Uell, Ülle, Ueve,
* Üxküll, Uffenbach.
* The ligatures Æ, , and the symbol ß, when used in English, French,
* or German, are normally not counted as separate alphabetic letters
* but as variants of AE, OE, and ss, respectively.
*/
$patterns = array("/à|á|â|ã|å|À|Á|Â|Ã|Å/",
"/ä|æ|Ä|Æ/",
"/ç|Ç/",
"/é|è|ê|ë|É|È|Ê|Ë/",
"/ì|í|î|ï|Ì|Í|Î|Ï/",
"/ñ|Ñ/",
"/ò|ó|ô|õ|ø|Ò|Ó|Ô|Õ|Ø/",
"/ö||Ö|/",
"/ß/",
"/ù|ú|û|Ù|Ú|Û/",
"/ü|Ü/",
"/ý|ÿ|Ý/");
$replace = array('a', 'ae', 'c', 'e', 'i',
'n', 'o', 'oe', 'ss', 'u', 'ue',
'y');
break;
default:
// 'en' (English), 'fr' (French)
/*
* In French and English, characters with diaeresis (ä, ë, ï, ö, ü, ÿ)
* are usually treated just like their un-accented versions.
* The ligatures Æ, , and the symbol ß, when used in English, French,
* or German, are normally not counted as separate alphabetic letters
* but as variants of AE, OE, and ss, respectively.
*
* NB: In French, accent differences are sorted from the end of the
* word, so the ordering of "pêche" and "péché" changes from the
* English ordering.
* English ordering: cote, coté, côte, côté
* French ordering: cote, côte, coté, côté
* => this is currently not supported
*/
$patterns = array("/à|á|â|ã|ä|å|À|Á|Â|Ã|Ä|Å/",
"/æ|Æ/",
"/ç|Ç/",
"/é|è|ê|ë|É|È|Ê|Ë/",
"/ì|í|î|ï|Ì|Í|Î|Ï/",
"/ñ|Ñ/",
"/ò|ó|ô|õ|ö|ø|Ò|Ó|Ô|Õ|Ö|Ø/",
"/|/",
"/ß/",
"/ù|ú|û|ü|Ù|Ú|Û|Ü/",
"/ý|ÿ|Ý/");
$replace = array('a', 'ae', 'c', 'e', 'i',
'n', 'o', 'oe', 'ss', 'u', 'y');
break;
}
return preg_replace($patterns,$replace,$string);
}
// English
function compareAccents_en($a, $b) {
return compareAccents($a, $b, 'en');
}
// French
function compareAccents_fr($a, $b) {
return compareAccents($a, $b, 'fr');
}
// German
function compareAccents_de($a, $b) {
return compareAccents($a, $b, 'de');
}
/*
* comparison function to group together accented letters with their lower-case
* non-accented counterparts
* the $lang parameter enables sorting rules for that language (ISO 639-1 code)
*/
function compareAccents($a, $b, $lang=null) {
$anew = strtolower(collatedLower($a,$lang));
$bnew = strtolower(collatedLower($b,$lang));
if ($anew < $bnew) return -1;
if ($anew > $bnew) return 1;
return 0;
}
// usage:
usort($myList,'compareAccents_fr');
// to be compared to:
setlocale(LC_COLLATE,'fr');
usort($myList, 'strcoll');
?>