Как выполнить сортировку без учета регистра в Javascript?

У меня есть массив строк, которые мне нужно отсортировать в Javascript, но в случае без учета регистра. Как это выполнить?

Ответ 1

В (почти:) однострочный

["Foo", "bar"].sort(function (a, b) {
    return a.toLowerCase().localeCompare(b.toLowerCase());
});

В результате получается

[ 'bar', 'Foo' ]

В то время как

["Foo", "bar"].sort();

приводит к

[ 'Foo', 'bar' ]

Ответ 2

myArray.sort(
  function(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) return -1;
    if (a.toLowerCase() > b.toLowerCase()) return 1;
    return 0;
  }
);

EDIT: Обратите внимание, что я изначально написал это, чтобы проиллюстрировать технику, а не иметь представление о производительности. Также см. Ответ @Ивана Кречетова для более компактного решения.

Ответ 3

arr.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    if (a == b) return 0;
    if (a > b) return 1;
    return -1;
});

Ответ 4

Если вы хотите гарантировать тот же порядок, независимо от порядка элементов во входном массиве, выполните стабильную сортировку:

myArray.sort(function(a, b) {
    /* Storing case insensitive comparison */
    var comparison = a.toLowerCase().localeCompare(b.toLowerCase());
    /* If strings are equal in case insensitive comparison */
    if (comparison === 0) {
        /* Return case sensitive comparison instead */
        return a.localeCompare(b);
    }
    /* Otherwise return result */
    return comparison;
});

Ответ 5

Нормализовать регистр в .sort() с помощью .toLowerCase().

Ответ 6

Вы также можете использовать оператор Элвиса:

arr = ['Bob', 'charley', 'fudge', 'Fudge', 'biscuit'];
arr.sort(function(s1, s2){
    var l=s1.toLowerCase(), m=s2.toLowerCase();
    return l===m?0:l>m?1:-1;
});
console.log(arr);

дает:

biscuit,Bob,charley,fudge,Fudge

Метод localeCompare, вероятно, хорош, хотя...

Примечание. Оператор Элвиса - это "тройной оператор" короткой формы, если тогда другое, обычно с присвоением. Если вы посмотрите на?: Боком, похоже, Элвис...
то есть вместо:

if (y) {
  x = 1;
} else {
  x = 2;
}

вы можете использовать:

x = y?1:2;

то есть. когда y истинно, затем верните 1 (для присвоения x), в противном случае возвратите 2 (для присваивания x).

Ответ 7

Вы также можете использовать новый Intl.Collator().compare, за MDN он более эффективно при сортировке массивов. Недостатком является то, что он не поддерживается старыми браузерами. MDN утверждает, что он вообще не поддерживается в Safari. Необходимо проверить это, поскольку в нем указано, что поддерживается Intl.Collator.

При сравнении большого количества строк, например при сортировке больших массивов, лучше создать объект Intl.Collator и использовать функцию, предоставленную свойством сравнения

["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]

Ответ 8

Другие ответы предполагают, что массив содержит строки. Мой метод лучше, потому что он будет работать, даже если массив содержит null, undefined или другие нестрочные.

var notdefined;
var myarray = ['a', 'c', null, notdefined, 'nulk', 'BYE', 'nulm'];

myarray.sort(ignoreCase);

alert(JSON.stringify(myarray));    // show the result

function ignoreCase(a,b) {
    return (''+a).toUpperCase() < (''+b).toUpperCase() ? -1 : 1;
}

null будет сортироваться между 'nulk' и 'nulm'. Но undefined будет всегда отсортирован последним.

Ответ 9

Это может помочь, если вы пытаетесь понять:

var array = ["sort", "Me", "alphabetically", "But", "Ignore", "case"];
console.log('Unordered array ---', array, '------------');

array.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    console.log("Compare '" + a + "' and '" + b + "'");

    if( a == b) {
        console.log('Comparison result, 0 --- leave as is ');
        return 0;
    }
    if( a > b) {
        console.log('Comparison result, 1 --- move '+b+' to before '+a+' ');
        return 1;
    }
    console.log('Comparison result, -1 --- move '+a+' to before '+b+' ');
    return -1;


});

console.log('Ordered array ---', array, '------------');


// return logic

/***
If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
***/

http://jsfiddle.net/ianjamieson/wmxn2ram/1/

Ответ 10

arr.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    if( a == b) return 0;
    if( a > b) return 1;
    return -1;
});

В вышеприведенной функции, если мы просто сравним, когда нижний регистр имеет два значения a и b, мы не получим приятного результата.

Например, если массив является [A, a, B, b, c, C, D, d, e, E] и мы используем указанную выше функцию, мы имеем именно этот массив. Это ничего не изменило.

Чтобы получить результат [A, a, B, b, C, c, D, d, E, e], мы должны сравнить снова, когда два значения нижнего регистра равны:

function caseInsensitiveComparator(valueA, valueB) {
    var valueALowerCase = valueA.toLowerCase();
    var valueBLowerCase = valueB.toLowerCase();

    if (valueALowerCase < valueBLowerCase) {
        return -1;
    } else if (valueALowerCase > valueBLowerCase) {
        return 1;
    } else { //valueALowerCase === valueBLowerCase
        if (valueA < valueB) {
            return -1;
        } else if (valueA > valueB) {
            return 1;
        } else {
            return 0;
        }
    }
}

Ответ 11

Оберните свои строки в / /i. Это простой способ использовать регулярное выражение для игнорирования обсадной колонны

Ответ 12

Я обернул верхний ответ в polyfill, поэтому я могу вызвать .sortIgnoreCase() в строковых массивах

// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
    Array.prototype.sortIgnoreCase = function () {
        return this.sort(function (a, b) {
            return a.toLowerCase().localeCompare(b.toLowerCase());
        });
    };
}