Olá pessoal,
Bom dia!
Neste post vou fazer uma abordagem bem simples sobre algo que muitos desenvolvedores .NET buscam na internet, como eu mesmo busquei essa solução, mas que é um pouco complicado de encontrar, pois a maioria das soluções postadas não funciona.
O meu problema era que eu utilizo muito uma função C# no meu CLR para listar arquivos de um diretório (Já havia postado essa função no post SQL Server – Como listar, ler, escrever, copiar, excluir e mover arquivos com o CLR (C#)), mas o fato dos arquivos não serem ordenados da forma correta sempre me incomodou, e eu resolvi melhorar isso.
Mesmo que você utilize uma cláusula ORDER BY para tentar ordenar, isso não vai funcionar, porque o SQL Server irá fazer a ordenação de strings utilização a ordenação alfanumérica.
Como funciona o algoritmo de ordenação de strings alfanuméricas
Esse tipo de algoritmo utiliza o código ASCII para ordenar os dados, comparando caractere por caractere até terminar a string ou o código ASCII de uma string for menor que o da outra. Desta forma, numa comparação entre Arquivo 100 e Arquivo 20, a comparação será feita da seguinte forma:
- Cada caractere da palavra “Arquivo” será comparada entre as 2 strings. Como elas são iguais, o algoritmo irá prosseguir para o restante da string
- O caractere “1” será comparado com o caractere “2”. Como ele é menor, a ordenação termina aí, colocando “Arquivo 100” antes de “Arquivo 20”
Como funciona o algoritmo de ordenação de strings Natural Sort
Assim como eu me incomodo com essa ordenação, que é a padrão pela grande maioria das linguagens de programação, muita gente também não gosta do “100” vir antes do “2000” e por para dar uma visão mais “humanizada”, foi-se criado o algoritmo de Natural Sort, que separa caracteres numéricos de letras, e os ordena separadamente. Os números são comparados de forma numérica (onde 100 é maior que 20), e as strings ele continua utilizando o código ASCII.
Para implementar o algoritmo Natural Sort, encontrei um código no blog do James McCormack para criar uma classe ICompare no C# e assim, ordenar os meus arquivos na minha função (e qualquer outra lista de arquivos que você precisar ordenar).
Visualizar Código-fonte da classe ICompareAgora eu preciso alterar a minha função de listar arquivos (também incluí uma flag booleana para listar arquivos dentro de subdiretórios ou não) e incluir uma função de OrderBy através da biblioteca LINQ.
Neste trecho:
1 |
foreach (var fileInfo in directories) |
Eu alterei para esse trecho:
1 |
foreach (var fileInfo in directories.OrderBy(fileInfo => fileInfo.Name, new NaturalSortComparer<string>())) |
E com isso, o nosso problema foi resolvido, onde temos o seguinte resultado:
Muito obrigado pela visita e até o próximo post!