Ho una matrice di stringhe che ho bisogno di ordinare in Javascript, ma in un caso insensibile. Come eseguire questo?Come eseguire l'ordinamento senza distinzione tra maiuscole e minuscole in Javascript?
risposta
In (quasi :) una battuta
["Foo", "bar"].sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
che si traduce in
[ 'bar', 'Foo' ]
Mentre
["Foo", "bar"].sort();
risultati in
[ 'Foo', 'bar' ]
Normalizza il caso nello .sort()
con .toLowerCase()
.
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a == b) return 0;
if (a > b) return 1;
return -1;
});
o '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: prega di notare che ho originariamente scritto questo per illustrare la tecnica piuttosto che la prestazione in mente. Si prega di fare riferimento anche a @Ivan Krechetov per una soluzione più compatta.
Questo può chiamare' toLowerCase' due volte su ogni stringa; sarebbe più efficiente memorizzare le versioni ridotte della stringa nelle variabili. – Jacob
Vero e grazie. L'ho scritto con chiarezza in mente, non con le prestazioni. Credo che dovrei notarlo. –
@Jacob Per essere giusti, la risposta accettata ha lo stesso problema di base: può eventualmente chiamare '.toLowerCase()' più volte per ogni elemento nell'array. Ad esempio, 45 chiamate alla funzione di confronto quando si ordinano 10 elementi in ordine inverso. 'var i = 0; ["z", "y", "x", "w", "v", "u", "t", "s", "r", "q"]. sort (funzione (a, b) {++ i; return a.toLowerCase(). localeCompare (b.toLowerCase());}); console.log ("Chiama per confrontare:" + i); // i === 45' – nothingisnecessary
Se si vuole garantire lo stesso ordine indipendentemente dall'ordine degli elementi dell'array di ingresso, ecco un ordinamento stable:
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;
});
È inoltre possibile utilizzare l'operatore di 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);
Gives :
biscuit,Bob,charley,fudge,Fudge
Il metodo localeCompare è probabilmente bene però ...
Nota: l'operatore Elvis è un "operatore ternario" di breve durata per il caso in cui altrimenti, di solito con incarico.
Se si guarda al:? Lateralmente, sembra che Elvis ...
cioè invece di:
if (y) {
x = 1;
} else {
x = 2;
}
è possibile utilizzare:
x = y?1:2;
cioè quando y è vero, allora return 1 (per assegnazione a x), altrimenti return 2 (per assegnazione a x).
Questo può aiutare se avete lottato per capire:
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;
});
In funzione di cui sopra, se si confronta proprio quando minuscolo due valori a e b, che non avrà il bel risultato.
Esempio: se l'array è [A, a, B, b, c, C, D, d, e, E] e usiamo la funzione sopra riportata, abbiamo esattamente quell'array. Non è cambiato nulla.
Per avere il risultato è [A, a, B, b, C, C, D, D, E, e], dovremmo confronta di nuovo quando due valore minuscole è uguale:
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;
}
}
}
Avvolgi le stringhe in / /i
. Questo è un modo semplice per usare regex per ignorare l'alloggiamento
Le altre risposte presuppongono che l'array contenga stringhe. Il mio metodo è migliore, perché funzionerà anche se l'array contiene null, indefiniti o altri non stringhe.
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;
}
Il null
verrà ordinata tra 'nulk' e 'nulm'. Ma lo undefined
sarà sempre in ordine ordinato.
' ('' + notdefined) === "undefined" 'così sarebbe stato ordinato prima" z " – MattW
@MattW no, ti stai sbagliando. vedi https://jsfiddle.net/qrw0uy3r/ –
Indovina che avrei dovuto cercare la definizione di 'Array.prototype.sort': | perché la parte about '('' + notdefined) ===" undefined "' * è veramente * true ... il che significa che se si capovolge il -1 e 1 nella funzione sort per invertire l'ordine, i tipi non definiti vengono ancora ordinati al fine. Deve anche essere considerato quando si usa la funzione di confronto al di fuori del contesto di un ordinamento di array (come lo sono stato quando mi sono imbattuto in questa domanda). – MattW
È anche possibile utilizzare il nuovo Intl.Collator().compare
, per MDN è more efficient quando si ordinano gli array. Lo svantaggio è che dal momento che non è supportato dai browser più vecchi. MDN afferma che non è supportato affatto in Safari. È necessario verificarlo, poiché indica che è supportato 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"]
Vecchi browser vecchi; Sto usando questo. –
ho avvolto la risposta superiore in una polyfill quindi posso chiamare .sortIgnoreCase() su matrici di stringhe
// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
Array.prototype.sortIgnoreCase = function() {
return this.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
};
}
È tempo di rivisitare questa vecchia domanda.
Non utilizzare soluzioni basate su toLowerCase
. Sono inefficienti e semplicemente non funzionano in alcune lingue (turco per esempio). Preferisco questo:
['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))
Controllare il documentation per la compatibilità del browser e tutto quello che c'è da sapere su l'opzione sensitivity
.
- 1. GetMethod senza distinzione tra maiuscole e minuscole?
- 2. AngularJs, senza distinzione tra maiuscole e minuscole
- 3. Elenco senza distinzione tra maiuscole e minuscole
- 4. Corrispondenza delle maiuscole senza distinzione tra maiuscole e minuscole
- 5. PHP in -array senza distinzione tra maiuscole e minuscole
- 6. come rendere la ricerca senza distinzione tra maiuscole e minuscole
- 7. JPA2: senza distinzione tra maiuscole e minuscole come l'abbinamento ovunque
- 8. Come sostituire una stringa senza distinzione tra maiuscole e minuscole
- 9. Ricerca senza distinzione tra maiuscole e minuscole in Mongo
- 10. Corrispondenza senza distinzione tra maiuscole e minuscole in Marpa
- 11. Come utilizzare PHP strpos senza distinzione tra maiuscole e minuscole?
- 12. Come rendere String.Contains senza distinzione tra maiuscole e minuscole?
- 13. OData e distinzione tra maiuscole e minuscole
- 14. Colonne stringa senza distinzione tra maiuscole e minuscole in SQLAlchemy?
- 15. ORACLE 11g senza distinzione tra maiuscole e minuscole per default
- 16. Underscore.js Ordinamento senza distinzione tra maiuscole e minuscole
- 17. Automapper - voglio distinzione tra maiuscole e minuscole
- 18. PHP: parametri senza distinzione tra maiuscole e minuscole
- 19. Set Matcher Bootstrap Typeahead senza distinzione tra maiuscole e minuscole
- 20. È possibile deserializzare GSON senza distinzione tra maiuscole e minuscole.
- 21. javascript: ignorando la distinzione tra maiuscole e minuscole delle stringhe
- 22. MySQL senza distinzione tra maiuscole e minuscole DISTINCT
- 23. Ricerca elenco senza distinzione tra maiuscole e minuscole
- 24. Doctrine LIKE senza distinzione tra maiuscole e minuscole
- 25. Elenco filtri Jquery senza distinzione tra maiuscole e minuscole
- 26. completamento scheda cshell, senza distinzione tra maiuscole e minuscole
- 27. Ricerca chiave senza distinzione tra maiuscole e minuscole di MemoryCache
- 28. Come eseguire una ricerca con accento e senza distinzione tra maiuscole e minuscole nel database MediaWiki?
- 29. È possibile eseguire una ricerca senza distinzione tra maiuscole e minuscole nell'istruzione LIKE in SQL?
- 30. Come rendere insensibile la distinzione tra maiuscole e minuscole?
Ricorda che le opzioni avanzate di localCompare non sono ancora supportate su tutte le piattaforme/browser. So che non sono usati in questo esempio, ma volevano solo aggiungere per chiarezza. [Vedi MDN per maggiori informazioni] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) –
Se vuoi coinvolgere localCompare(), potresti basta usare * la sua * capacità di non fare distinzione tra maiuscole e minuscole, ad esempio: 'return a.localeCompare (b, 'en', {'sensitivity': 'base'});' –
+1 per non chiamare 'toLowerCase()' quando 'localeCompare' lo fa già di default in alcuni casi. Puoi leggere ulteriori informazioni sui parametri per passare ad esso qui: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Parameters – Milimetric