Пользовательская сортировка Javascript со специальными символами тире (-) и подчеркиванием (_) - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь выполнить пользовательскую сортировку, как показано ниже:

  1. специальный символ (- первый, _ последний)
  2. цифра
  3. алфавиты

Например, если я сортирую ниже

var words = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'];

, результат должен быть

MBC-PEP-1,MBC-PEP_1,MBC-PEP01,MBC-PEP91,MBC-PEPA1,MBC-PEPZ1

, используя мой код, результат будет ниже

"MBC-PEP-1", "MBC-PEP01", "MBC-PEP91", "MBC-PEP_1", "MBC-PEPA1", "MBC-PEPZ1"

но мне нужен приведенный выше порядок сортировки, не знаю, как этого добиться.

function MySort(alphabet)
{
    return function(a, b) {
        var lowerA = a.toLowerCase()
        var lowerB = b.toLowerCase()
        var index_a = alphabet.indexOf(lowerA[0]),
        index_b = alphabet.indexOf(lowerB[0]);

        if (index_a === index_b) {
            // same first character, sort regular
            if (a < b) {
                return -1;
            } else if (a > b) {
                return 1;
            }
            return 0;
        } else {
            return index_a - index_b;
        }
    }
}

var items = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'],
sorter = MySort('-_0123456789abcdefghijklmnopqrstuvwxyz');

console.log(items.sort(sorter));

Ответы [ 3 ]

0 голосов
/ 14 декабря 2018

Вы смотрите только на первый символ в вашем алгоритме.Вы должны проверить больше вашей строки / следующих символов.Вот быстрое решение с использованием рекурсии:

function MySort(alphabet)
{
    return function recSorter(a, b) {
        var lowerA = a.toLowerCase()
        var lowerB = b.toLowerCase()
        var index_a = alphabet.indexOf(lowerA[0]),
        index_b = alphabet.indexOf(lowerB[0]);

        if (index_a === index_b && index_a >= 0) {
            return recSorter(a.slice(1), b.slice(1));
        } else {
            return index_a - index_b;
        }
    }
}

var items = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'],
sorter = MySort('-_0123456789abcdefghijklmnopqrstuvwxyz');

console.log(items.sort(sorter));

Я не уверен, что вы хотите, чтобы происходило, когда у вас разная длина строк, символов вне алфавита или в других случаях.Для приведенного примера это приводит к ожидаемому порядку.

0 голосов
/ 14 декабря 2018

Как сказал Нариго в своем ответе, вы сравниваете только первого персонажа.Вот другая идея, которая, вероятно, проще:

function MySort(a, b) {
  a = a.replace("_", ".");
  b = b.replace("_", ".");
  return a.localeCompare(b);
}

var items = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'];

console.log(items.sort(MySort));

Мы в основном используем обычное сравнение строк, за исключением того, что мы меняем подчеркивание на точку, чтобы определить порядок, поскольку он совместим с тем, чего вы пытаетесь достичь.

0 голосов
/ 14 декабря 2018

Я перенес ответ с здесь на JavaScript, который делает то, что вы хотите, без использования рекурсии или чего-то слишком сложного:

function MySort(alphabet) {
    return function (a, b) {
       a = a.toLowerCase();
       b = b.toLowerCase();
       var pos1 = 0;
       var pos2 = 0;
       for (var i = 0; i < Math.min(a.length, b.length) && pos1 == pos2; i++) {
          pos1 = alphabet.indexOf(a[i]);
          pos2 = alphabet.indexOf(b[i]);
       }

       if (pos1 == pos2 && a.length != b.length) {
           return o1.length - o2.length;
       }

       return pos1 - pos2;
    };
}
    
var items = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'],
sorter = MySort('-_0123456789abcdefghijklmnopqrstuvwxyz');

console.log(items.sort(sorter));
...