Хорошо, у меня есть раздел кода, который сортирует имена в алфавитном порядке.

Однако код не обрабатывает десятичные дроби так, как я бы хотел.

Оно упорядочивает имя следующим образом (я бы предпочел, чтобы оно увеличивалось численно):

Было бы заказать это:

  • APPLE - 1.0051
  • APPLE - 1.1071
  • APPLE - 11,1592
  • APPLE - 12.0692
  • ЯБЛОКО - 12.1717
  • APPLE - 2.0186 << это должно быть после "APPLE - 1.1071", очевидно
  • ЯБЛОКО - 21.1407
  • APPLE - 22,089
  • APPLE - 23,069
  • БАНАНА - 1.0051
  • БАНАНА - 1.1071
  • БАНАНА - 11,1592
  • БАНАНА - 12.0692
  • БАНАНА - 12.1717
  • BANANA - 2.0186 << это должно быть после "BANANA - 1.1071", очевидно
  • БАНАНА - 21.1407
  • БАНАНА - 22,089
  • БАНАНА - 23.069

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

function(a, b){
         var nameA=a.myname.toLowerCase(), nameB=b.myname.toLowerCase()
         if (nameA < nameB) //sort string ascending
          return -1 
         if (nameA > nameB)
          return 1
         return 0 //default return value (no sorting)
    }

С уважением, Джонни

2
Jonny 26 Янв 2013 в 22:51

5 ответов

Лучший ответ

Демонстрация и вот источник + небольшое объяснение:

function fruit_sort(a, b) {
    var parts = {
        a: a.split('-'),
        b: b.split('-')
    };
    if (parts.a[0] == parts.b[0]) // strings are the same
        return parseFloat(parts.a[1]) - parseFloat(parts.b[1]); // sort by number
    return parts.a[0] > parts.b[0] ? 1 : -1; // sort by string
}
var arr = ["APPLE - 1.0051",
    "APPLE - 1.1071",
    "APPLE - 11.1592",
    "APPLE - 12.0692",
    "BANANA - 1.0051",
    "BANANA - 1.1071",
    "BANANA - 11.1592",
    "BANANA - 12.0692",
    "BANANA - 12.1717",
    "APPLE - 12.1717",
    "APPLE - 2.0186",
    "APPLE - 21.1407",
    "BANANA - 23.069",
    "APPLE - 22.089",
    "APPLE - 23.069",
    "BANANA - 2.0186",
    "BANANA - 21.1407",
    "BANANA - 22.089"];
arr.sort(fruit_sort);
console.log(arr);
// outputs
[
    "APPLE - 1.0051",
    "APPLE - 1.1071",
    "APPLE - 2.0186",
    "APPLE - 11.1592",
    "APPLE - 12.0692",
    "APPLE - 12.1717",
    "APPLE - 21.1407",
    "APPLE - 22.089",
    "APPLE - 23.069",
    "BANANA - 1.0051",
    "BANANA - 1.1071",
    "BANANA - 2.0186",
    "BANANA - 11.1592",
    "BANANA - 12.0692",
    "BANANA - 12.1717",
    "BANANA - 21.1407",
    "BANANA - 22.089",
    "BANANA - 23.069"
]

Сначала функция разбивает термины на их текстовые и числовые части - если текст четный, она сортирует только по значению parseFloat числового значения - в противном случае сначала сортируется по строковому значению.

3
rlemon 26 Янв 2013 в 20:23

Вот похожее решение на другой странице: Javascript неправильно сортирует ДЕСЯТИЧНЫЕ числа

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

1
Community 23 Май 2017 в 12:24

Попробуйте этот код:

function (x, y) {
    x=x.myname;
    y=y.myname;

    var nameA = x.toLowerCase().split("-")[0],
        nameB = y.toLowerCase().split("-")[0]
    if (nameA < nameB) //sort string ascending
    return -1
    if (nameA > nameB) return 1
    var floatExtract = /(([1-9][0-9]*\.?[0-9]*)|(\.[0-9]+))([Ee][+-]?[0-9]+)?/;
    if (floatExtract.test(x) && floatExtract.test(y)) {
        x = x.match(floatExtract)[1];
        y = y.match(floatExtract)[1];
        if (!isNaN(parseFloat(x)) && !isNaN(parseFloat(y))) {
            x = parseInt(x);
            y = parseInt(y);
        }
        return ((x > y) ? 1 : ((x < y) ? -1 : 0));
    }
    return 0;
}

Он разбивает вашу строку и делает простое сравнение с первой частью [перед дефисом], затем ищет плавающее внутри вашей строки и выполняет другую сортировку в списке по этому ...

Демонстрация | источник

2
extramaster 26 Янв 2013 в 20:32

Хорошо, я использовал пример кода rlemon и отредактировал его следующим образом:

function(a, b) {
var parts = {
    a: a.myname.split(' - '),
    b: b.myname.split(' - ')
};
if (parts.a[0] == parts.b[0]) // strings are the same
    return parseFloat(parts.a[1]) - parseFloat(parts.b[1]); // sort by number
return parts.a[0] > parts.b[0] ? 1 : -1; // sort by string

}

0
Jonny 26 Янв 2013 в 20:47

Как предложил @Steve Wellens в своем комментарии, я изменил ваш существующий фрагмент, чтобы сначала сравнить текстовые части, а затем в случае совпадения сравнить числовые части строки, преобразовав их в float s. Если вы хотите отсортировать исключительно по числовой части строки, то ответ @extramaster вам пригодится.

function(a, b){
        var parts, textPartA, textPartB, numericPartA, numericPartB;

        parts = a.split('-');
        textPartA = parts[0];
        numericPartA = parseFloat(parts[1]);

        parts = b.split('-');
        textPartB = parts[0];
        numericPartB = parseFloat(parts[1]);

        //sort by text first
        if(textPartA < textPartB) {
            return -1;
        }
        if(textPartA > textPartB) {
            return 1;
        }

        //text parts are equal, now sort by the numeric parts
        if(numericPartA < numericPartB){
            return -1;
        }
        if(numericPartA > numericPartB){
            return 1;
        }

        return 0;
    }

@Jonny: Быстрый пример

2
gowansg 26 Янв 2013 в 20:25