Problems with sorting an array list

1

I have the following problem:

I try to sort a list of people containing the flag that identifies the person (student or Teacher), the person's code, the person's name, the person's status (active, inactive, blocked) and the status of participation in that room (active, inactive, and locked), all this information inside a vector that I call arrayVelhoAux . In this I want to sort this vector alphabetically (A, B, C, D, E, ...).

arrayVelhoAux.FLG_IDENT_PESSO = arrayCursor[j].FLG_IDENT_PESSO;
arrayVelhoAux.COD_IDENT_PESSO = pessoa.COD_IDENT_PESSO;
arrayVelhoAux.TXT_NOMEX_PESSO = pessoa.TXT_NOMEX_PESSO;
arrayVelhoAux.FLG_STATU_PESSO = pessoa.FLG_STATU_PESSO;
arrayVelhoAux.FLG_STATU_PARTC = arrayCursor[j].FLG_STATU_PARTC;

arrayVelho.push(arrayVelhoAux);

To fill this vector I am looping because there are data I get in other tables. After the total completion of this vector I make a .sort() in order to sort it.

arrayVelho.sort(compareArray);

In compareArray , I simply compare which one is larger. Put all uppercase letters so that they are all compared in the same size.

function compareArray(a1,b1) {
    if(a1.TXT_NOMEX_PESSO.toUpperCase() > b1.TXT_NOMEX_PESSO.toUpperCase()) return 1;
    if(a1.TXT_NOMEX_PESSO.toUpperCase() < b1.TXT_NOMEX_PESSO.toUpperCase()) return -1;
    return 0;
}

Apparently there is nothing wrong, and something interesting happens because you are only comparing some, others are out of order. As in the image below.

I would like to know if there is a better solution than it is, or if you would like to arrange and leave this solution 100% functional.

    
asked by anonymous 08.04.2016 / 13:45

1 answer

3

Renan, it is interesting that you return an integer instead of a boolean.

var nomes = ["Alessandro", "Alessandra", "Alexandre", "Aline", "Antônio", "Breno", "Bruna", "Carlos", "Carla", "Célia", "Cecília", "César", "Danilo", "Dalila", "Deneval", "Eduardo", "Eduarda", "Esther", "Elísio", "Fábio", "Fabrício", "Fabrícia", "Félix", "Felícia", "Feliciano", "Frederico", "Fabiano", "Gustavo", "Guilherme", "Gúbio", "Heitor", "Hélio", "Hugo", "Isabel", "Isabela", "Ígor", "João", "Joana", "Júlio César", "Júlio", "Júlia", "Janaína", "Karla", "Kléber", "Lucas", "Lorena", "Lorraine", "Larissa", "Ladislau", "Marcos", "Meire", "Marcelo", "Marcela", "Margarida", "Mércia", "Márcia", "Marli", "Morgana", "Maria", "Norberto", "Natália", "Nataniel", "Núbia", "Ofélia", "Paulo", "Paula", "Pablo", "Pedro", "Raul", "Rafael", "Rafaela", "Ricardo", "Roberto", "Roberta", "Sílvia", "Sílvia", "Silas", "Suélen", "Sara", "Salvador", "Sirineu", "Talita", "Tertuliano", "Vicente", "Víctor", "Vitória", "Yango", "Yago", "Yuri", "Washington", "Warley"];

//colocar os itens do array em um ordem aleatoria.
var suffle = function (nome1, nome2) {
  return Math.random() * 10;
}

var compare = function (nome1, nome2) {
  if ( nome1 < nome2 )
    return -1;
  if ( nome1 > nome2 )
    return 1;
  return 0;
}
var orderAsc = function(nome1, nome2) {  
  return compare(nome1, nome2) * 1;
}
var orderDesc = function(nome1, nome2) {  
  return compare(nome1, nome2) * -1;
}

nomes.sort(suffle);
console.log(nomes);

nomes.sort(orderAsc);
console.log(nomes);

nomes.sort(suffle);
console.log(nomes);

nomes.sort(orderDesc);
console.log(nomes);

Note that in the above case, the name Ígor was not ordered as expected, it appears at the end of the array (orderAsc) or at start (orderDesc);

To solve this problem, you can use Intl.Collator, it will return an integer as a result of the comparison, and it has some additional options that can help you with the comparison of strings.

var nomes = ["Alessandro", "Alessandra", "Alexandre", "Aline", "Antônio", "Breno", "Bruna", "Carlos", "Carla", "Célia", "Cecília", "César", "Danilo", "Dalila", "Deneval", "Eduardo", "Eduarda", "Esther", "Elísio", "Fábio", "Fabrício", "Fabrícia", "Félix", "Felícia", "Feliciano", "Frederico", "Fabiano", "Gustavo", "Guilherme", "Gúbio", "Heitor", "Hélio", "Hugo", "Isabel", "Isabela", "Ígor", "João", "Joana", "Júlio César", "Júlio", "Júlia", "Janaína", "Karla", "Kléber", "Lucas", "Lorena", "Lorraine", "Larissa", "Ladislau", "Marcos", "Meire", "Marcelo", "Marcela", "Margarida", "Mércia", "Márcia", "Marli", "Morgana", "Maria", "Norberto", "Natália", "Nataniel", "Núbia", "Ofélia", "Paulo", "Paula", "Pablo", "Pedro", "Raul", "Rafael", "Rafaela", "Ricardo", "Roberto", "Roberta", "Sílvia", "Sílvia", "Silas", "Suélen", "Sara", "Salvador", "Sirineu", "Talita", "Tertuliano", "Vicente", "Víctor", "Vitória", "Yango", "Yago", "Yuri", "Washington", "Warley"];

//colocar os itens do array em um ordem aleatoria.
var suffle = function (nome1, nome2) {
  return Math.random() * 10;
}

var collator = new Intl.Collator("pt-BR", { sensitivity : "base" });
var orderAsc = function(nome1, nome2) {  
  return collator.compare(nome1, nome2) * 1;
}
var orderDesc = function(nome1, nome2) {  
  return collator.compare(nome1, nome2) * -1;
}

nomes.sort(suffle);
console.log(nomes);

nomes.sort(orderAsc);
console.log(nomes);

nomes.sort(suffle);
console.log(nomes);

nomes.sort(orderDesc);
console.log(nomes);

Note that I used the option sensitivity : "base" , in this case the comparison will be case-insensitive and accent-sensitive , so there is no need to make a .toUpperCase() , and the sort order will present the expected result even if the words have accents.

However since safari still does not support Intl.Collator (And you still talk bad about IE; D), then maybe you need to use a Polyfill: Intl.js

    
08.04.2016 / 14:40