Multidimensional array sort with UTF8 collator locale special characters

The ‘correct’ alphabetical sorting is highly dependent on the locale.  Some countries sort the special characters to the end and some not.  A variety of so called solutions were found on the web, but few were clean enough and covered my special case.  A generic multidimensional array needed to be sorted by a realtime set of fields with variable sort directions.

A combination of  a uasort with a user defined comparision function that used php’s collator class saved the day.  A swap routine helped achieve any change in sort direction.

Do please let me know if there is a cleaner more efficient way to sort multidimensional arrays by user defined columns with user defined sort directions in wordpress for a locale defined by wordpress.

Multidimensional array sort with UTF8 collator locale special characters
Test data sorted under different locales

I had to resort to globals to pass the ‘realtime’ sortfields and the locale (array(field1=>sortdirection, etc).

The quick test function was:

function do_sort(&$arr, $locale, $sortfields) {
global $collator, $sortfields;
$collator = new collator($locale);
if (empty($sortfields or !is_array($sortfields))) return $arr;
uasort ($arr, function ( $a, $b) {
global $collator, $sortfields;
foreach ($sortfields as $fld1 => $sort1) {
// really only until return!
if (empty ($a[$fld1])) $aa = '';
else $aa = $a[$fld1];
if (empty ($b[$fld1])) $bb = '';
else $bb = $b[$fld1];
if ($sort1 == SORT_DESC) amr_swap($aa, $bb);
$cmp = $collator->compare($aa, $bb);
if (!($cmp == 0)) return $cmp;
}
return $cmp;
}
);
return $arr;
}

The test code is provided in a test_utf8_sort2 Zip for your fun.

Some reference links noted during the process:

  • https://stackoverflow.com/questions/41602514/custom-collation-with-php-using-usort
  • custom alphabet function: https://stackoverflow.com/questions/7929796/how-can-i-sort-an-array-of-utf-8-strings-in-php
  • https://stackoverflow.com/questions/38171550/trying-to-sort-a-multidimensional-array-by-a-sub-value-with-special-characters
  • https://stackoverflow.com/questions/18210189/mysql-order-by-on-column-with-unicode-characters
  • https://mathiasbynens.be/notes/mysql-utf8mb4#comment-83
  • https://stackoverflow.com/questions/43212197/sorting-php-array-with-locale-setting
  • use db rather with unicode: https://wordpress.stackexchange.com/questions/170450/alphabetical-sorting-local-language

For wordpress queries, what was not working in the wp users screen sortable columns, did work when queried directly:

SELECT * FROM `beta_usermeta` WHERE `meta_key` = "first_name" ORDER BY `meta_value` COLLATE utf8mb4_unicode_520_ci