Sort words with accents in PHP

Asked

Viewed 1,551 times

6

I am trying to alphabetically sort an array in PHP, where the key of each array position is a word.

I’m using the function ksort. Sorting works, the problem is that accented words such as "acid" are placed at the end of the list.

I need to have the accented letters sorted in the same way as accented letters and the procedure does not require much processing.

2 answers

8


Test like this, using:

$palavras = array('ambiente', 'anão', 'anã', 'pai', 'país', 'ácido');
function compareASCII($a, $b) {
    $at = iconv('UTF-8', 'ASCII//TRANSLIT', $a);
    $bt = iconv('UTF-8', 'ASCII//TRANSLIT', $b);
    return strcmp($at, $bt);
}

uasort($palavras, 'compareASCII');
var_dump($palavras);

The result is:

array(6) {
  [5]=>
  string(6) "ácido"
  [0]=>
  string(8) "ambiente"
  [2]=>
  string(4) "anã"
  [1]=>
  string(5) "anão"
  [3]=>
  string(3) "pai"
  [4]=>
  string(5) "país"
}

Source: https://stackoverflow.com/a/10649560/2256325

That function uasort(<array>, <função>) accept as second parameter another function to compare the array values.

  • I was looking at the same answer as the stack overflow. I find it interesting to explain how the functions u*sort work in php (through callback and etc).

  • This function works to sort array values. But in case I need to sort array keys.

  • @Térciogarcia subtitua o a for k. I think there is an even more detailed explanation of the behavior of the Sort functions.

  • Got it now, it worked with uksort. Thank you!

  • @gmsantos I will add more of daqwui a little, thank you

  • Why then, for example, the name Marília comes before Marcela? Test with an array with these two names and see.

Show 1 more comment

1

To solution that Sérgio indicated didn’t work for me, since, for some reason, she put the words that start with accent before the rest of the words:

array(4) {
    ["Ética_Profissional"]=>
    array(2) {
        [0]=>
        int(12864)
        [1]=>
        int(12862)
    }
    ["Computação_Aplicada"]=>
    array(1) {
        [0]=>
        int(12861)
    }
    ["Geologia_Ambiental_e_Recursos_Hídricos"]=>
    array(1) {
        [0]=>
        int(11803)
        }
    ["Socioeconomia_e_Sustentabilidade"]=>
    array(1) {
        [0]=>
        int(12858)
    }
}

However, I did find in this post a solution that worked for me:

$key_values = array(
    'Geologia_Ambiental_e_Recursos_Hídricos'    => array( 11803 ),
    'Computação_Aplicada'                       => array( 12861 ),
    'Socioeconomia_e_Sustentabilidade'          => array( 12858 ),
    'Ética_Profissional'                        => array( 12864, 12862 ),
);
function comparar_palavras($name1,$name2){
    $patterns = array(
        'a' => '(á|à|â|ä|ã|Á|À|Â|Ä|Ã)',
        'e' => '(é|è|ê|ë|É|È|Ê|Ë)',
        'i' => '(í|ì|î|ï|Í|Ì|Î|Ï)',
        'o' => '(ó|ò|ô|ö|õ|Ó|Ò|Ô|Ö|Õ)',
        'u' => '(ú|ù|û|ü|Ú|Ù|Û|Ü)'
    );          
    $name1 = preg_replace(array_values($patterns), array_keys($patterns), $name1);
    $name2 = preg_replace(array_values($patterns), array_keys($patterns), $name2);          
    return strcasecmp($name1, $name2);
}
uksort($key_values, "comparar_palavras");

The result is:

array(4) {
    ["Computação_Aplicada"]=>
    array(1) {
        [0]=>
        int(12861)
    }
    ["Ética_Profissional"]=>
    array(2) {
        [0]=>
        int(12864)
        [1]=>
        int(12862)
    }
    ["Geologia_Ambiental_e_Recursos_Hídricos"]=>
    array(1) {
        [0]=>
        int(11803)
    }
    ["Socioeconomia_e_Sustentabilidade"]=>
    array(1) {
        [0]=>
        int(12858)
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.