Сортировать массив javascript так, чтобы пустые значения всегда были внизу - PullRequest
11 голосов
/ 24 ноября 2011

Итак, у меня есть массив массивов, которые содержат только строки. Массив массивов должен отображаться в виде таблицы и может иметь более 1000 строк с 20 или более значениями в каждой.

например:

var arr = [
    ["bob","12","yes"],
    ["joe","","no"],
    ["tim","19","no"],
    ["dan","","yes"],
    ["tim","",""],
    ["dan","0",""]
]

строки могут содержать все, что может быть представлено в виде строки, в том числе: " ", "", "0" или "00-00-00" и т. Д. ... и любой столбец, который можно использовать для упорядочения.

Я сортирую массивы по возрастанию и по убыванию, но некоторые значения, по которым я сортирую, являются пустыми строками: "". Как я могу сделать так, чтобы пустые строки (только) всегда были в конце новых массивов во всех современных браузерах?

В настоящее время они находятся в конце при подъеме, но в начале при спуске.

Я сортирую, как показано ниже (Да, я уверен, что могу сделать это и короче):

if (direction == "asc") {
    SortedArr = arr.sort(function (a, b) {
        if (a[colToSortBy] == '') {
            return -1;
        }
        if (a[colToSortBy].toUpperCase() < b[colToSortBy].toUpperCase()) {
            return -1;
        }
        if (a[colToSortBy].toUpperCase() > b[colToSortBy].toUpperCase()) {
            return 1;
        }
        return 0;
    });
} else {
    SortedArr = arr.sort(function (a, b) {
        if (a[colToSortBy] == '') {
            return -1;
        }
        if (b[colToSortBy].toUpperCase() < a[colToSortBy].toUpperCase()) {
            return -1;
        }
        if (b[colToSortBy].toUpperCase() > a[colToSortBy].toUpperCase()) {
            return 1;
        }
        return 0;
    });
}

Ответы [ 4 ]

5 голосов
/ 24 ноября 2011

Пустые строки в конце

Рабочий пример в JSFiddle, который всегда ставит пустые строки в конец независимо от того, является ли порядок восходящим или нисходящим.Это может быть проблемой юзабилити, но это решение:

if (direction == "asc") {
    SortedArr = arr.sort(function (a, b) {
        return (a[col] || "|||").toUpperCase().localeCompare((b[col] || "|||").toUpperCase())
    });
} else {
    SortedArr = arr.sort(function (a, b) {
        return (b[col] || "!!!").toUpperCase().localeCompare((a[col] || "!!!").toUpperCase())
    });
}
0 голосов
/ 29 декабря 2015

Я использовал этот способ в своем приложении ...

Вы можете настроить его, чтобы получить благоприятный результат. у нас также есть номер. MAX_SAFE_INTEGER

var arr = [10, "", 8, "", 89, 72]

var min = Number.MIN_SAFE_INTEGER

var sorted = arr.sort(function (a,b) {
  return (a || min) - (b || min)
})

var cons = document.getElementById("console")

cons.innerText = "Ascending " + JSON.stringify(sorted) + "\n" + "Descending " +  JSON.stringify(sorted.reverse())
<html>
  <head></head>
  <body>
    <p id="console"></p>
  </body>
</html>
0 голосов
/ 19 июля 2013

Я пишу приложение, которое должно работать на IE, FF, Safari, Chrome, Opera, Desktop, Tablet (включая iPad) и телефонах (включая iPhone). Это означает, что я продолжаю тестирование в разных браузерах. Таким образом, я обнаружил, что моя процедура сортировки ниже не работала правильно в FF, пока я не добавил часть кода «новый раздел». Причина в том, что я не позаботился о сортировке, когда числовое значение не указано (тире, -). FF также не работал правильно с отрицательными (-) значениями. Этот код теперь отлично работает для:

if (SortByID == 0) {                //string values (Bank Name)
    myValues.sort( function (a,b) {
        var nameA = a[SortByID].toUpperCase(), nameB = b[SortByID].toUpperCase();
        if (SortOrderID == 1) {         //sort string ascending
            if (nameA < nameB) { return -1; } else { if (nameA > nameB) { return 1; } }
        } else {                        //sort string descending
            if (nameA < nameB) { return 1; } else { if (nameA > nameB) { return -1; } }
        }
        return 0                    //default return value (no sorting)
    })
} else {                            //numeric values (Items)
    myValues.sort(function (a, b) {
        if (isNumber(a[SortByID]) && isNumber(b[SortByID])) { //
            if (SortOrderID == 1) { //sort number ascending
                return parseFloat(a[SortByID]) - parseFloat(b[SortByID]);
            } else {                //sort string descending
                return parseFloat(b[SortByID]) - parseFloat(a[SortByID]);
            }
        } else { //one of the values is not numeric
            //new section
            if (!isNumber(a[SortByID])) {
                if (SortOrderID == 1) { //sort number ascending
                    return -1;
                } else {                //sort number descending
                    return 1;
                }
            } else {
                if (!isNumber(b[SortByID])) {
                    if (SortOrderID == 1) { //sort number ascending
                        return 1;
                    } else {                //sort number descending
                        return -1;
                    }
                }
            }//New section
            return 0;
        }
    })
}

Я знаю, что это долго, но мне достаточно просто понять. Я надеюсь, что это также решает проблему браузера, поднятую Крисом Дж. * isNumber - простая функция, проверяющая значение! isNAN

0 голосов
/ 24 ноября 2011

Я думаю, что ваша проблема связана с тем, что вы проверяете, является ли a[colToSortBy] пустой строкой, но вы не делаете это для b[colToSortBy].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...