Mam tablicę ciągów, które muszę sortować w JavaScript, ale w sposób niewrażliwy na wielkość liter. Jak to wykonać?Jak przeprowadzić sortowanie niewrażliwe na wielkość liter w JavaScript?
Odpowiedz
W (prawie :) one-liner
["Foo", "bar"].sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
co skutkuje
[ 'bar', 'Foo' ]
podczas
["Foo", "bar"].sort();
wyników w
[ 'Foo', 'bar' ]
Normalizacja obudowy w .sort()
z .toLowerCase()
.
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a == b) return 0;
if (a > b) return 1;
return -1;
});
lub "return a === b? 0: a> b? 1: -1; ' –
myArray.sort(
function(a, b) {
if (a.toLowerCase() < b.toLowerCase()) return -1;
if (a.toLowerCase() > b.toLowerCase()) return 1;
return 0;
}
);
EDIT: Należy pamiętać, że pierwotnie napisałem to, aby zilustrować technikę zamiast wydajność w umyśle. Proszę również zapoznać się z odpowiedzią @Ivan Krechetov dla bardziej zwartego rozwiązania.
To może wywołać' toLowerCase' dwa razy na każdym ciągu; byłoby bardziej skuteczne przechowywanie obniżonych wersji łańcucha w zmiennych. – Jacob
Prawda i dzięki. Napisałem to z myślą o jasności, a nie wydajności. Chyba powinienem to zauważyć. –
@Jacob Aby być uczciwym, zaakceptowana odpowiedź ma ten sam podstawowy problem: może wywołać '.toLowerCase()' wiele razy dla każdego elementu w tablicy. Na przykład 45 wywołań funkcji porównywania podczas sortowania 10 elementów w odwrotnej kolejności. 'var i = 0; ["z", "y", "x", "w", "v", "u", "t", "s", "r", "q"]. sort (funkcja (a, b) {++ i; return a.toLowerCase(). localeCompare (b.toLowerCase());}); console.log ("Połączenia do porównania:" + i); // i === 45' – nothingisnecessary
Jeśli chcesz, aby zapewnić taką samą kolejność niezależnie od kolejności elementów tablicy wejściowej, tutaj jest stable Sortowanie:
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;
});
Można również użyć operatora Elvis:
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);
daje :
biscuit,Bob,charley,fudge,Fudge
Sposób localeCompare jest chyba w porządku, chociaż ...
Uwaga: Operator Elvis jest krótką formą "operatora trójskładnikowego", jeśli jeszcze, zwykle z przydziałem.
Jeśli spojrzeć na: bokiem, wygląda jak Elvis ...
czyli zamiast:
if (y) {
x = 1;
} else {
x = 2;
}
można użyć:
x = y?1:2;
tj gdy y jest prawdą, a następnie return 1 (dla przypisania do x), w przeciwnym razie zwraca 2 (dla przypisania do x).
To może pomóc, jeśli starali się zrozumieć:
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.
***/
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if(a == b) return 0;
if(a > b) return 1;
return -1;
});
W powyższej funkcji, jeśli po prostu porównać gdy małe litery dwie wartości aib, nie będziemy mieli ładny wynik.
Przykład, jeśli tablica to [A, a, B, b, c, C, D, d, e, E] i używamy powyższej funkcji, mamy dokładnie tą tablicę. Nic nie zmienia.
Aby uzyskać wynik w [A, A, B, B, C, C, D, D, E, k], to należy porównać ponownie po dwóch dolna wartość przypadku jest równa:
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;
}
}
}
Owiń swoje struny w / /i
. Jest to łatwy sposób użycia regex do ignorowania obudowy
Pozostałe odpowiedzi zakładają, że tablica zawiera ciągi. Moja metoda jest lepsza, ponieważ zadziała, nawet jeśli tablica zawiera wartości null, undefined lub inne nie-łańcuchowe.
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;
}
The null
zostaną posortowane między '' i 'nulk nulm'. Jednak undefined
zawsze będzie sortowany jako ostatni.
' ('' + notdefined) === "undefined" ', więc będzie sortować wcześniej" z " – MattW
@MattW Nie masz racji. zobacz https://jsfiddle.net/qrw0uy3r/ –
Zgadnij, że powinienem znaleźć definicję 'Array.prototype.sort': | ponieważ część dotycząca '('' + notdefined) ===" undefined "' * naprawdę jest * true ... co oznacza, że jeśli odwrócisz -1 i 1 w funkcji sortowania, aby odwrócić kolejność, undefined nadal sortuje do koniec. Trzeba go również wziąć pod uwagę przy korzystaniu z funkcji porównania poza kontekstem sortowania w tablicy (tak jak wtedy, gdy natknąłem się na to pytanie). – MattW
Możesz także użyć nowego Intl.Collator().compare
, na MDN to more efficient podczas sortowania tablic. Minusem jest to, że nie jest obsługiwany przez starsze przeglądarki. MDN stwierdza, że nie jest w ogóle obsługiwane w Safari. Należy go zweryfikować, ponieważ stwierdza, że obsługiwana jest wersja Intl.Collator
.
When comparing large numbers of strings, such as in sorting large arrays, it is better to create an Intl.Collator object and use the function provided by its compare property
["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]
Przykręć stare przeglądarki; Używam tego. –
ja owinięty górna odpowiedź w PolyFill więc mogę zadzwonić .sortIgnoreCase() na tablicach smyczkowych
// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
Array.prototype.sortIgnoreCase = function() {
return this.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
};
}
To jest czas, aby ponownie ten stary pytanie.
Nie powinieneś używać rozwiązań polegających na toLowerCase
. Są one nieefektywne i po prostu nie działają w niektórych językach (na przykład turecki). Wolę to:
['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))
Sprawdź documentation kompatybilności przeglądarki i wszystko, co trzeba wiedzieć na temat opcji sensitivity
.
- 1. JavaScript: niewrażliwe na wielkość liter
- 2. sortowanie niewrażliwe na wielkość liter przy użyciu danych sprężystych
- 3. Wyszukiwanie niewrażliwe na wielkość liter w Mongo
- 4. Adresy niewrażliwe na wielkość liter dla Django?
- 5. Jak mogę zrobić rozróżnianie wielkości liter niewrażliwe na wielkość liter?
- 6. Niewrażliwe na wielkość liter JFlex regex
- 7. Wybrane opcje niewrażliwe na wielkość liter
- 8. Uruchamianie kwerendy niewrażliwe na wielkość liter
- 9. JPA2: Niewrażliwe na wielkość liter jak dopasowanie wszędzie
- 10. Jak mogę uzyskać Browser.text.include? być niewrażliwe na wielkość liter?
- 11. Wyszukiwanie niewrażliwe na wielkość liter MySQL na polu varbinary?
- 12. Znajdź wyszukiwania niewrażliwe na wielkość liter w linii
- 13. Wyszukiwanie niewrażliwe na wielkość liter przy użyciu Hibernate
- 14. JavaScript zawiera przypadek niewrażliwe
- 15. Alfanumeryczne sortowanie wrażliwe na wielkość liter w postgresie
- 16. ORACLE 11g niewrażliwe na wielkość domyślnie
- 17. Czy w OpenGrok można przeprowadzić wyszukiwanie uwzględniające wielkość liter?
- 18. Dopasowywanie niewrażliwe na wielkość znaków w języku Marpa
- 19. Lodash: jak zrobić sortowanie niewrażliwe na wielkość kolekcji za pomocą polecenia orderBy?
- 20. Jak włączyć autouzupełnianie niewrażliwe na wielkość dla NSComboBox?
- 21. Dodawaj wielkość liter bez sortowania do PostgreSQL
- 22. Jak zrobić wyrażenie regularne niewrażliwe na wielkość liter w programie Go?
- 23. Railsy validates_uniqueness_of w wielu kolumnach z niewrażliwością na wielkość liter
- 24. Jaki jest najczystszy sposób na przetwarzanie niewrażliwe na wielkość liter w Text.Combinators.Parsec?
- 25. NSMutableArray Sortowanie - sprawa niewrażliwe
- 26. Jak tworzyć zapytania niewrażliwe na wielkość liter przy użyciu modeli Django
- 27. Lista niewrażliwa na wielkość liter
- 28. Jak ustawić operator% like% na wielkość liter?
- 29. Wybierz wielkość liter w LINQ
- 30. Nieczułe na wielkość liter zamień na
Należy pamiętać, że zaawansowane opcje localeCompare nie są jeszcze obsługiwane na wszystkich platformach/przeglądarkach. Wiem, że nie są używane w tym przykładzie, ale po prostu chciałem dodać dla jasności. [Zobacz MDN po więcej informacji] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) –
Jeśli zamierzasz włączyć localeCompare(), możesz po prostu używaj * jego * zdolności do rozróżniania małych i wielkich liter, np .: 'return a.localeCompare (b, 'en', {'sensitivity': 'base'});' –
+1 dla nie wywoływania 'toLowerCase()' kiedy 'localeCompare' robi to już domyślnie w niektórych przypadkach. Możesz przeczytać więcej na temat parametrów, które należy przekazać tutaj: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Parameters – Milimetric