Categories: Tecnologia

Comparando strings em Javascript e porque parece errado

Muitas vezes Javascript é motivo de piadas/memes de alguém dizendo que o funcionamento do Javascript é estranho quando compara algumas coisas. Mas em geral, isso é só falta de conhecimento de como a linguagem funciona por baixo dos panos.

E uma desses tipos de comparações que parecem erradas é a comparação de strings.

Comparando strings

Strings são comparadas caracter por caracter e em ordem alfabética. Algumas regras importantes são:

  • Uma letra minúscula é sempre maior que a mesma letra maiúscula:
    • console.log("a" > "Z"); //true
  • Letras com marcas/sinais diacríticas são “fora de ordem”:
    • console.log("Österreich" > "Zealand"); //true

Marcas diacríticas são sinais gráficos que são adicionados a uma letra ou grifo para indicar um significado específico como a pronúncia ou a diferenciação entre palavras. Cedilha, acento agudo, crase, acento circunflexo são exemplos de diacríticos.

Essa regra das marcas diacríticas pode causar estranhamento se tentarmos por exemplo ordenar uma lista de países em ordem alfabética. A maioria imaginaria que “Zealand” viria depois de “Österreich” o que não é verdade.

Encoded strings

Para entender porque isso acontece precisamos entrar no Javascript de maneira mais profunda, observando que strings são encoded em UTF-16, ou seja, cada caractere tem um número correspondente. Você pode verificar isso executando str.codePointAt(pos):

console.log("Z".codePointAt(0)); //90
console.log("z".codePointAt(0)); //122

Também dá para fazer o caminho inverso, criando um caractere a partir da sua representação numérica:

console.log(String.fromCodePoint(90)); //Z

Se a gente quisesse imprimir todos os caracteres do alfabeto (latino) em uma string o código seria:

let str = "";

for (let i = 65; i <= 220; i++) {
    str += String.fromCodePoint(i);
}

console.log(str); // ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„
// ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜ

Se você reparou bem, percebeu que as letras maiúsculas vem antes das minúsculas, e todas elas antes das letras com acentos. É por esse motivo que a > Z. Os caracteres são comparados por seus códigos numéricos. Quando comparamos strings o caractere “maior” significa que o código daquele caractere é maior do que o outro.

Comparando strings do jeito certo

O algoritmo correto para comparar strings pode ser mais complexo do que parece porque alfabetos são diferentes para idiomas diferentes. Então, o browser precisa saber o idioma que queremos comparar.

Felizmente, browsers modernos suportam internacionalização provendo um método especial para comparar strings em idiomas diferentes seguindo regras.

Chamar str.localeCompare(str2) retorna um inteiro indicando se str é menor, igual ou maior que str2 de acordo com as regras do idioma:

  • Retorna um número negativo se str é menor que str2.
  • Retorna um número positivo se str é maior que str2.
  • Retorna 0 se str e str2 são equivalentes.
console.log("Österreich".localeCompare("Zealand")); //-1

Esse método (localeCompare) tem mais 2 argumentos adicionais, que permitem especificar o idioma (por padrão pego do ambiente, ordem das letras depende do idioma) e configurar regras adicionais como case sensitive ou se ”a”e ”á” deveriam ser tratadas como a mesma coisa, etc.

Referências

André Felizardo

Share
Published by
André Felizardo

Recent Posts

Blockchain & Cripto

Desvendando o Potencial da Blockchain e Criptomoedas através da Criptografia Em um mundo onde a…

1 ano ago

Automatize o deploy de uma aplicação React com Github Actions e FTP

O deploy de uma aplicação React é uma etapa crucial para disponibilizar sua criação na…

2 anos ago

Github Satellite 2020 – Muitas novidades

Satellite 2020 foi a primeira conferência virtual do Github. O Github já tinha sido liberado…

5 anos ago

Web Components – Guia Geral

Neste guia veremos o que são web components, quando usar, sua estrutura e também um…

5 anos ago

Tipos de Frontend

A alguns anos atrás escrevi um texto sobre o que é o frontend, também palestrei…

5 anos ago

SVG – Guia definitivo

O que é SVG é a sigla para Scalable Vector Graphics que traduzindo seria gráficos…

5 anos ago