Existe um JavaScript strcmp ()?


Respostas:


134

A respeito

str1.localeCompare(str2)

localeCompare () parecia bom, mas parecia que era apenas para MS, ou não no padrão, na melhor das hipóteses.

10
que padrão você está olhando? parece ser em ECMA-262 secção padrão 15.5.4.9, bem como no Mozilla Javascript referência ( developer.mozilla.org/en/Core_JavaScript_1.5_Reference/... )
newacct

newacct está absolutamente correto. Este parece ser o padrão ECMAScript. Provavelmente a melhor solução neste caso.
coderjoe 24/07/2009

3
localeCompare()às vezes se comporta de maneira diferente em cada navegador.
Varda Elentári 23/03

1
@ VardaElentári: Apenas para personagens que não têm ordem lexical no local especificado. Para caracteres que fazem e navegadores que não restringem quais partes do Unicode eles usam, os resultados são consistentes e definidos pelo ECMA-402 e Unicode .
TJ Crowder

38

Javascript não tem, como você aponta.

Uma pesquisa rápida surgiu com:

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 ) );
}

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

Obviamente, você pode adicionar o localeCompare, se necessário:

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

E use em str1.localeCompare(str2)qualquer lugar, sem ter que se preocupar com o envio do navegador local. O único problema é que você teria que adicionar suporte localeseoptions se você se importa com isso.


Eu acho que essa é uma boa maneira de lidar com isso (detecção de recursos e polyfill FTW), mas se o desempenho da micro velocidade é tão importante quanto à necessidade desse método, então eu estou um pouco confuso que ==é usado e não, ===pois o último evita conversão de tipo e, portanto, é esse micro segundo mais rápido.
Tokimon

uma nota sobre a localeCompare polyfill-- não diferencia maiúsculas de minúsculas, de modo a tornar o polyfill também não diferencia maiúsculas e minúsculas que você pode fazer algo como- var a = this.toUpperCase(); var b = str.toUpperCase(); return ((a == b) ? 0 : ((a > b) ? 1 : -1));
Kip

22

localeCompare()é lento ; portanto, se você não se importa com a ordem "correta" de cadeias de caracteres que não sejam do inglês, tente seu método original ou a aparência mais limpa:

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

Esta é uma ordem de magnitude mais rápida do que localeCompare()na minha máquina.

Os +garante que a resposta é sempre numérico ao invés de boolean.


Dois erros: não retorna 0 para str1 == str2, não retorna 1 para str1> str2
stackunderflow

2
@stackunderflow Estou usando com sucesso em uma função de classificação. Qual é o bug que você está enfrentando?
1 ''

1
Isso retornará -1, falso ou verdadeiro em vez de -1, 0 ou 1. Para que ele retorne números sempre, ajuste-o assim: str1 <str2? -1: + (str1> str2)
jfren484

2
Mais uma coisa (estou usando isso no código que estou escrevendo agora, por isso estou aperfeiçoando): esteja ciente de que essa é uma comparação que diferencia maiúsculas de minúsculas ('Foo' virá antes de 'bar', mas ' Bar 'virá depois de' foo '). Isso corresponde à pergunta do OP sobre strcmp, mas muitas pessoas podem vir aqui procurando uma comparação independente de caso.
precisa saber é

5
Aqui está uma expressão de aparência ainda mais limpa:(str1 > str2) - (str1 < str2)
Jonathan Gilbert


-1

E se:

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

Então, para comparar s1 com 2:

s1.strcmp(s2)

1
Seria bom se você dissesse por que eles não deveriam fazer o que fizeram. Eu poderia entender se eles estavam alterando como um método de função existente funcionava, mas, neste caso, eles estão adicionando um novo.
Relaxando em Chipre

2
Estender protótipos incondicionalmente como esse geralmente é um grande não-não.
214 Christopher Christopher
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.