Esiste JavaScript strcmp ()?


Risposte:


134

Che dire

str1.localeCompare(str2)

localeCompare () sembrava buono, ma sembrava che fosse solo MS, o non nello standard al massimo.

10
quale standard stai guardando? sembra essere nella sezione standard ECMA-262 15.5.4.9, così come nel riferimento Javascript mozilla ( developer.mozilla.org/en/Core_JavaScript_1.5_Reference/… )
newacct

newacct è assolutamente corretto. Questo sembra essere lo standard ECMAScript. Probabilmente la migliore soluzione in questo caso.
coderjoe,

3
localeCompare()a volte si comporta diversamente su ogni browser.
Varda Elentári,

1
@ VardaElentári: solo per personaggi che non hanno un ordinamento lessicale in una determinata località. Per i personaggi che lo fanno e i browser che non limitano le parti di Unicode che usano, i risultati sono coerenti e definiti da ECMA-402 e Unicode .
TJ Crowder,

38

Javascript non ce l'ha, come fai notare.

Una rapida ricerca ha prodotto:

function strcmp ( str1, str2 ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Waldo Malqui Silva
    // +      input by: Steve Hilder
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +    revised by: gorthaur
    // *     example 1: strcmp( 'waldo', 'owald' );
    // *     returns 1: 1
    // *     example 2: strcmp( 'owald', 'waldo' );
    // *     returns 2: -1

    return ( ( str1 == str2 ) ? 0 : ( ( str1 > str2 ) ? 1 : -1 ) );
}

da http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_strcmp/

Ovviamente, potresti semplicemente aggiungere localeCompare se necessario:

if (typeof(String.prototype.localeCompare) === 'undefined') {
    String.prototype.localeCompare = function(str, locale, options) {
        return ((this == str) ? 0 : ((this > str) ? 1 : -1));
    };
}

E utilizzalo str1.localeCompare(str2)ovunque, senza doversi preoccupare se il browser locale è stato fornito con esso. L'unico problema è che dovresti aggiungere supporto localeseoptions se ti interessa.


Penso che questo sia un bel modo di gestirlo (rilevamento delle funzionalità e polyfill FTW), ma se le prestazioni della micro velocità sono così importanti, come per la necessità di questo metodo, allora sono un po 'perplesso che ==viene utilizzato e non ===poiché quest'ultimo evita conversione del tipo e quindi è quel micro secondo più veloce.
Tokimon,

una nota sul polyfill-- localeCompare non fa distinzione tra maiuscole e minuscole, quindi per rendere anche il polyfill non sensibile al maiuscolo / minuscolo potresti fare qualcosa del genere- var a = this.toUpperCase(); var b = str.toUpperCase(); return ((a == b) ? 0 : ((a > b) ? 1 : -1));
Kip

22

localeCompare()è lento , quindi se non ti interessa l'ordine "corretto" di stringhe di caratteri non inglesi, prova il tuo metodo originale o l'aspetto più pulito:

str1 < str2 ? -1 : +(str1 > str2)

Questo è un ordine di grandezza più veloce rispetto localeCompare()alla mia macchina.

Le +assicura che la risposta è sempre numerico anziché booleana.


Due bug: non restituisce 0 per str1 == str2, non restituisce 1 per str1> str2
stackunderflow

2
@stackunderflow Lo sto usando con successo in una funzione di ordinamento. Qual è il bug che riscontri?
1 ''

1
Questo restituirà -1, falso o vero invece di -1, 0 o 1. Per farlo restituire sempre i numeri, modificalo in questo modo: str1 <str2? -1: + (str1> str2)
jfren484,

2
Un'altra cosa (lo sto usando nel codice che sto scrivendo proprio ora, quindi l'ho perfezionato): basta essere consapevoli del fatto che si tratta di un confronto sensibile al maiuscolo / minuscolo ("Foo" verrà prima di "bar" ma " Bar "verrà dopo" pippo "). Ciò corrisponde alla domanda di OP su strcmp, ma molte persone potrebbero venire qui alla ricerca di un confronto case-agnostico.
jfren484,

5
Ecco un'espressione ancora più pulita:(str1 > str2) - (str1 < str2)
Jonathan Gilbert,

2
var strcmp = new Intl.Collator(undefined, {numeric:true, sensitivity:'base'}).compare;

Uso: strcmp(string1, string2)

Risultato: 1significa che string1 è più grande, 0significa uguale, -1significa che string2 è più grande.

Questo ha prestazioni più elevate di String.prototype.localeCompare

Inoltre, lo numeric:truefa fare un confronto logico dei numeri



-1

Che ne dite di:

String.prototype.strcmp = function(s) {
    if (this < s) return -1;
    if (this > s) return 1;
    return 0;
}

Quindi, per confrontare s1 con 2:

s1.strcmp(s2)

1
Sarebbe d'aiuto se dicessi perché non dovrebbero fare quello che hanno fatto. Potrei capire se stavano alterando il funzionamento di un metodo di funzione esistente, ma in questo caso ne stanno aggiungendo uno nuovo.
Rilassarsi a Cipro il

2
L'estensione incondizionata di prototipi come questo è generalmente un grande no-no.
Christopher
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.