php array sorting with accents

2020-06-16 10:20发布

问题:

I am using this to sort according to last name:

  usort($fb_friends['data'], "custom_sort");          
  function custom_sort($a,$b) { 
    return $a['last_name']>$b['last_name'];
  }

  foreach($fb_friends['data'] as $friend) { 
    echo '<br>'; 
    echo $friend['name']; 
  } 

But - when in last name is accent, e.g. Šiko, Áron, etc, these names are at the end. How can I sort it properly?

回答1:

Use multi-byte string functions. There is a function called strcoll which seems to suit your needs.

More info:

  • On how to sort an array of UTF-8 strings
  • How to sort an array of UTF-8 strings?

EDIT: added Peter's working code, below

setlocale(LC_COLLATE, 'sk_SK.utf8');

usort($fb_friends['data'], 'custom_sort');

function custom_sort($a, $b) {
    return strcoll ($a['last_name'], $b['last_name']);
}

foreach ($fb_friends['data'] as $friend) {
    echo '<br>';
    echo $friend['name'];
}


回答2:

What comes first?

  • A
  • a
  • ث

This is defined by a Collation.

PHP has the Collator class for this: https://www.php.net/manual/en/class.collator.php

Example:

$array = [ 'A', 'a', '文', 'ث' ];

// Brazilian Portuguese
$collator = new Collator('pt_BR');

$collator->asort( $array );

print_r( $array );

Returns:

Array
(
    [1] => a
    [0] => A
    [3] => ث
    [2] => 文
)

Now with a Chinese collation new Collator('zh'):

Array
(
    [2] => 文
    [1] => a
    [0] => A
    [3] => ث
)

You can try it yourself here: https://3v4l.org/0vsBR

The first argument receives a locale. I couldn't find information about what locales are valid, it seems that different systems have different naming schemes for locales, but if you stick with RFC 1766 or ISO 639 you will be fine.