Cómo ordenar las calificaciones de letras en Javascript sin un índice manual
sorting (7)
Tratando de descubrir cómo ordenar una serie de calificaciones de letras correctamente
[''A+'', ''A'', ''A-'', ''B+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''F'']
.
La función de clasificación estándar no lo hace.
También estoy buscando hacer esto
sin establecer un índice manual
para cada calificación de letra.
const grades = [''B+'', ''F'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''A'']
grades.sort((a, b) => {
return a - b;
});
console.log(grades);
Rendimiento esperado:
[''A+'', ''A'', ''A-'', ''B+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''F'']
Aquí está mi solución usando matemáticas simples 🧮:
const grades = [''B+'', ''F'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''A'']
const getCounter = (letter) => {
// Making simple math to sort it out
let letterCounter = letter.charCodeAt(0) * 10;
if(letter[1] === "+"){
letterCounter -= 1;
}
else if(letter[1] === "-"){
letterCounter += 1;
}
return letterCounter;
}
grades.sort((a, b) => {
return getCounter(a) - getCounter(b);
});
console.log(grades)
// Print => [''A+'',''A'',''A-'',''B+'',''B'',''B-'',''C+'',''C'',''C-'',''D+'',''D'',''D-'',''F'']
En realidad más simple de lo que piensas:
const grades = [''B+'', ''F'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''A'']
res = grades
.map(x => x + '','')
.sort()
.map(x => x.slice(0, -1))
console.log(res.join())
La "magia" aquí es que
,
está justo entre
+
y
-
en la tabla ascii, entonces
A
convierte en
A,
y se clasifica entre
A+
y
A-
.
Como sugirió Nina, también puede colocar la cosa
+,
directamente en la devolución de llamada de
sort
:
const grades = [''B+'', ''F'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''A'']
let cmp = (x, y) => (x > y) - (x < y);
res = grades.sort((x, y) => cmp(x + '','', y + '',''))
console.log(...res)
donde
cmp
es el reemplazo del pobre para el
operador
<=>
Pocas formas de hacerlo. Una forma es dividir los personajes y comparar las partes.
const grades = [''B+'', ''A'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''F'']
const sorted = grades.sort((a, b) => {
if (a === b) return 0 // if equal nothing changes
const ap = a.split('''') // separate into letter and sign
const bp = b.split('''')
if (ap[0] === bp[0]) { // if first letter is the same, we have to check second
return (ap[1] === "+" || b[1] === "-") ? -1 : 1
}
return ap[0].localeCompare(b[0]) // sort by letter grade
})
console.log(sorted)
Prueba esto.
const grades = [''B+'', ''A'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''F'']
const sortGrades = function (grades) {
const result = grades.sort(function (a, b) {
if (a[0] < b[0]) {
return -1;
}
if (b[0] > a[0]) {
return 1;
}
if(a[0] === b[0]) {
if(a[1] && a[1] === "+") {
return -1;
}
}
return 0;
});
return result;
};
sortGrades(grades)
Puede separar las calificaciones y tomar un objeto para los símbolos de postfix.
const grades = [''B+'', ''A'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''F'']
grades.sort((a, b) => {
const order = { ''+'': -1, ''-'': 1, undefined: 0 };
return a[0].localeCompare(b[0]) || order[a[1]] - order[b[1]];
});
console.log(...grades);
Si solo desea atenerse a los valores ASCII:
const grades = [''B+'', ''F'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''A'']
grades.sort((a, b) =>
a.charCodeAt(0) === b.charCodeAt(0) // If the letters are the same
? (a.charCodeAt(1) || 44) - (b.charCodeAt(1) || 44) // Just compare the postfix
: a.charCodeAt(0) - b.charCodeAt(0) // Otherwise compare the letters
);
console.log(...grades);
El valor ACII de
+
es 43 y el valor ASCII de
-
es 45, por lo que podemos usar 44 (que es) cuando no hay postfix.
Alternativamente, usando literales de plantilla:
const grades = [''B+'', ''F'', ''A-'', ''A+'', ''B'', ''B-'', ''C+'', ''C'', ''C-'', ''D+'', ''D'', ''D-'', ''A'']
grades.sort((a, b) =>
a.charCodeAt(0) === b.charCodeAt(0)
? `${a},`.charCodeAt(1) - `${b},`.charCodeAt(1)
: a.charCodeAt(0) - b.charCodeAt(0)
);
console.log(...grades);
puedes probar algo como:
const symbols = [''+'', undefined, ''-'']
function sort(a, b) {
if (a[0] !== b[0]) return a > b ? 1 : -1
return symbols.indexOf(a[1]) > symbols.indexOf(b[1]) ? 1 : -1
}
primero verifica la letra, luego el modificador (si lo hay)