sort - Como classificar notas de letras em Javascript sem um índice manual




sort array obj javascript (5)

Aqui está minha solução usando matemática 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']

Tentando descobrir como classificar uma matriz de notas corretamente ['A+', 'A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'D-', 'F'] . A função de classificação padrão não funciona. Também estou procurando fazer isso sem definir um índice manual para cada nota da 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);

Saída esperada:

['A+', 'A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'D-', 'F']


Na verdade, mais simples do que você pensa:

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())

A "mágica" aqui é que , está bem entre + e - na tabela ascii, então A se torna A, e classifica entre A+ e A- .

Como Nina sugeriu, você também pode colocar a coisa +, diretamente no sort retorno de chamada:

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)

onde cmp é o substituto do pobre homem para o operador <=>


Se você deseja apenas manter os 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);

O valor ACII de + é 43 e o valor ASCII de - é 45, portanto, podemos usar 44 (ou seja , ) quando não houver postfix.

Como alternativa, usando literais de modelo:

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);


Tente isso.

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)

você pode tentar 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
}

verifica primeiro a letra e depois o modificador (se houver)





sorting