Aqui está o número da versão do software:
"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"
Como posso comparar isso? Suponha que a ordem correta seja:
"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"
A idéia é simples ...: Leia o primeiro dígito, depois o segundo, depois o terceiro .... Mas não consigo converter o número da versão em número flutuante .... Você também pode ver o número da versão como isto:
"1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1.0"
e isso é mais claro para ver qual é a idéia por trás ... Mas, como convertê-lo em um programa de computador? Alguém tem alguma idéia de como classificar isso? Obrigado.
javascript
sorting
Tattat
fonte
fonte
Respostas:
A idéia básica para fazer essa comparação seria usar
Array.split
para obter matrizes de partes das seqüências de entrada e comparar pares de partes das duas matrizes; se as partes não forem iguais, sabemos qual versão é menor.Há alguns detalhes importantes a serem lembrados:
Aqui está o código para uma implementação que você pode usar diretamente (lista com documentação ):
Esta versão compara partes naturalmente , não aceita sufixos de caracteres e considera "1.7" menor que "1.7.0". O modo de comparação pode ser alterado para lexicográfico e as seqüências de versão mais curtas podem ser preenchidas com zero automaticamente usando o terceiro argumento opcional.
Existe um JSFiddle que executa "testes de unidade" aqui ; é uma versão ligeiramente expandida do trabalho de ripper234 (obrigado).
Nota importante: Este código usa
Array.map
eArray.every
, o que significa que ele não será executado nas versões do IE anteriores a 9. Se você precisar dar suporte a eles, precisará fornecer polyfills para os métodos ausentes.fonte
sempre
O analisador de versão semântica usado pelo npm.
$ npm install semprever
Link de versão semântica :
https://www.npmjs.com/package/semver#prerelease-identifiers
fonte
fonte
var len = Math.min(a_components.length, b_components.length);
fará com que as versões 2.0.1.1 e 2.0.1 sejam tratadas como iguais, não é?a = '7'
eb = '7.0'
devoluções-1
porque 7.0 é mais longo. Tem alguma sugestão para isso? (console.log(compare("7", "7.0")); //returns -1
)Essa função de comparação muito pequena, mas muito rápida, aceita números de versão de qualquer tamanho e qualquer tamanho de número por segmento .
Valores de retorno:
- um número
< 0
se a <b- um número
> 0
se a> b-
0
se a = bEntão você pode usá-lo como função de comparação para Array.sort ();
EDIT: Versão corrigida com bug removendo zeros à direita para reconhecer "1" e "1.0.0" como iguais
fonte
["0.0.0", "0.0", "0.4.1", "0.5", "1.0.0", "1", "1.1", "1.2.15", "1.25.4", "2", "2.5.0", "2.5.10", "2.5.10.4159", "10.5"]
onde o seu código gera["0.0", "0.0.0", "0.4.1", "0.5", "1", "1.0.0", "1.1", "1.2.15", "1.25.4", "2", "2.5.0", "2.5.10", "2.5.10.4159", "10.5"]
, o que é perfeitamente o mesmo, já que 0,0 e 0,0,0 são considerados iguais , o que significa que é irrelevante se '0,0' é anterior a '0,0,0' ou vice-versa.Retirado de http://java.com/js/deployJava.js :
fonte
Não foi possível encontrar uma função fazendo o que eu queria aqui. Então eu escrevi o meu. Esta é a minha contribuição. Espero que alguém ache útil.
Prós:
Lida com seqüências de versão de comprimento arbitrário. '1' ou '1.1.1.1.1'.
O padrão é cada valor para 0 se não for especificado. Só porque uma string é mais longa não significa que é uma versão maior. ('1' deve ser o mesmo que '1.0' e '1.0.0.0'.)
Compare números e não cadeias. ('3' <'21' deve ser verdadeiro. Não falso.)
Não perca tempo com comparações inúteis no loop. (Comparando para ==)
Você pode escolher seu próprio comparador.
Contras:
Meu código, semelhante à resposta aceita por Jon :
Exemplos :
fonte
Função simples e curta:
Testes:
fonte
Perdoe-me se essa idéia já foi visitada em um link que eu não vi.
Eu tive algum sucesso com a conversão das partes em uma soma ponderada da seguinte forma:
O que tornou as comparações muito fáceis (comparando um duplo). Nossos campos de versão nunca têm mais que 4 dígitos.
Espero que isso ajude alguém, pois os vários condicionais parecem um pouco exagerados.
fonte
Aqui está outra versão curta que funciona com qualquer número de sub-versões, zeros acolchoados e números pares com letras (1.0.0b3)
Resultado:
0 : a = b
1 : a> b
-1 : a <b
Mostrar snippet de código
https://jsfiddle.net/vanowm/p7uvtbor/
fonte
2017 resposta:
Código mais simples para navegadores modernos:
A idéia aqui é comparar números, mas na forma de string. para fazer a comparação funcionar, as duas cadeias devem ter o mesmo comprimento. tão:
"123" > "99"
tornar-se"123" > "099"
preenchendo o número curto "consertar" a comparação
Aqui, preencho cada parte com zeros com comprimentos de 10. Em seguida, basta usar uma comparação simples para a resposta
Exemplo:
fonte
compareVersion2
que exatamente acontece?substring
em vez depadStart
para uma melhor compatibilidade istovar zeros = "0000000000"; '0.2.32'.split('.').map( s => zeros.substring(0, zeros.length-s.length) + s ).join('.')
lhe dará0000000000.0000000002.0000000032
:)Verifique a função
version_compare()
do projeto php.js . É semelhante ao PHPversion_compare()
.Você pode simplesmente usá-lo assim:
fonte
Minha resposta menos detalhada do que a maioria das respostas aqui
fonte
Embora essa pergunta já tenha muitas respostas, cada uma promove sua própria solução preparada no quintal, enquanto temos todo um ecossistema de bibliotecas testadas para isso.
Uma pesquisa rápida no NPM , GitHub , X nos dará algumas bibliotecas adoráveis, e eu gostaria de ler algumas:
semver-compare
é uma ótima biblioteca leve (~ 230B) que é especialmente útil se você deseja classificar por números de versão, à medida que o método exposto da biblioteca retorna-1
,0
ou de forma1
apropriada.O núcleo da lib:
compare-semver
é bastante robusto em tamanho (~ 4.4kB gzipped), mas permite algumas comparações únicas, como encontrar o mínimo / máximo de uma pilha de versões ou descobrir se a versão fornecida é única ou menor do que qualquer outra coisa em uma coleção de versões.compare-versions
é outra outra pequena lib (~ 630B compactada com gzip) e segue bem as especificações, o que significa que você pode comparar versões com sinalizadores alfa / beta e até curingas (como nas versões secundárias / patches:1.0.x
ou1.0.*
)Aponte o ponto: nem sempre é necessário copiar e colar o código do StackOverflow, se você pode achar decente (unidade) testado versões através do seu gerenciador de pacotes de sua escolha.
fonte
Eu enfrentei um problema semelhante e já havia criado uma solução para ele. Sinta-se livre para experimentá-lo.
Retorna
0
paraequal
,1
se a versão forgreater
e-1
se forless
fonte
A idéia é comparar duas versões e saber qual é a maior. Nós excluímos "." e comparamos cada posição do vetor com a outra.
fonte
fonte
A
replace()
função substitui apenas a primeira ocorrência na sequência. Então, vamos substituir o.
com,
. Depois exclua tudo.
e faça o,
para.
novamente e analise-o para flutuar.finalmente, classifique-o:
fonte
Confira esta postagem no blog . Esta função funciona para números de versão numéricos.
fonte
Se, por exemplo, quisermos verificar se a versão atual do jQuery é menor que 1,8,
parseFloat($.ui.version) < 1.8 )
daria um resultado errado se a versão for "1.10.1", pois o retorno de parseFloat ("1.10.1")1.1
. Uma comparação de string também daria errado, pois"1.8" < "1.10"
avalia comofalse
.Então, precisamos de um teste como este
A seguinte função lida com isso corretamente:
aqui estão alguns exemplos:
Veja aqui uma amostra ao vivo e um conjunto de testes: http://jsfiddle.net/mar10/8KjvP/
fonte
Aqui está uma implementação de coffeescript adequada para uso com o Array.sort inspirado em outras respostas aqui:
fonte
Eu escrevi um módulo de nó para classificar versões, você pode encontrá-lo aqui: version-sort
Características :
Não hesite em abrir um problema se precisar de outro recurso.
fonte
Isso funciona para versões numéricas de qualquer tamanho, separadas por um ponto. Ele retornará true somente se myVersion for> = minimumVersion, assumindo que a versão 1 seja menor que 1.0, a versão 1.1 seja menor que 1.1.0 e assim por diante. Deve ser bastante simples adicionar condições extras, como aceitar números (apenas converter em uma string) e hexadecimal ou dinamizar o delimitador (basta adicionar um parâmetro de delimitador e substituir o "." Pelo parâmetro)
Aqui estão alguns testes:
Como alternativa, aqui está uma versão recursiva
fonte
Acho uma maneira mais simples de compará-los, não tenho certeza se é o que você deseja. quando eu corro abaixo do código no console, faz sentido, e usando o método sort (), eu poderia obter a sequência ordenada de versões das strings. é baseado na ordem alfabética.
fonte
Você poderia usar
String#localeCompare
comoptions
fonte
undefined
idioma acima? Como é que você consegue postar isso enquanto eu leio os outros;)undefined
é a parte das localidades, não é usada aqui.você não poderia convertê-los em números e depois classificar após o tamanho? Anexar 0 aos números com comprimento <4
brincou no console:
quanto maior a versão, maior o número. Editar: provavelmente precisa ser ajustado para incluir séries de versões maiores
fonte
Este é um truque legal. Se você estiver lidando com valores numéricos, entre um intervalo específico de valores, poderá atribuir um valor a cada nível do objeto de versão. Por exemplo, "largestValue" está definido como 0xFF aqui, o que cria uma aparência muito "IP" para seu controle de versão.
Isso também lida com versões alfanuméricas (ou seja, 1.2a <1.2b)
fonte
Gosto da versão do @ mar10 , embora, do meu ponto de vista, exista uma chance de uso indevido (parece que não é o caso se as versões são compatíveis com o documento Semantic Versioning , mas pode ser o caso se algum "número de compilação" for usado ):
O problema aqui é que os subnúmeros do número da versão são, em alguns casos, escritos com zeros à direita cortados (pelo menos como eu o vi recentemente usando um software diferente), o que é semelhante à parte racional de um número, portanto:
O primeiro (ou o primeiro e o segundo) subnúmero da versão, no entanto, sempre é tratado como um valor inteiro ao qual realmente é igual.
Se você usar esse tipo de controle de versão, poderá alterar apenas algumas linhas no exemplo:
Assim, cada sub-número exceto o primeiro será comparada como um float, então
09
e1
vai se tornar0.09
e0.1
em conformidade e em comparação corretamente desta forma.2054
e3
se tornará0.2054
e0.3
.A versão completa, então, é (créditos para @ mar10 ):
PS: É mais lento, mas também é possível pensar em reutilizar a mesma função de comparação, operando o fato de que a string é realmente a matriz de caracteres:
fonte
Fiz isso com base na ideia do Kons e o otimizei para a versão Java "1.7.0_45". É apenas uma função destinada a converter uma string de versão em um float. Esta é a função:
A sequência "1.7.0_45" é convertida em 1.0070000450000001 e isso é bom o suficiente para uma comparação normal. Erro explicado aqui: Como lidar com a precisão do número de ponto flutuante em JavaScript? . Se precisar de mais de três dígitos em qualquer parte, você pode alterar o divisor
Math.pow(10, i * 3);
.A saída terá a seguinte aparência:
fonte
Eu tive o mesmo problema de comparação de versões, mas com versões possivelmente contendo qualquer coisa (ou seja: separadores que não eram pontos, extensões como rc1, rc2 ...).
Eu usei isso, que basicamente divide as seqüências de versão em números e não-números, e tenta comparar de acordo com o tipo.
Existem algumas suposições aqui para alguns casos, por exemplo: "1.01" === "1.1" ou "1.8" <"1.71". Falha ao gerenciar "1.0.0-rc.1" <"1.0.0", conforme especificado pelo Semantic versionning 2.0.0
fonte
Pré-processar as versões anteriores à classificação significa que parseInt não é chamado várias vezes desnecessariamente. Usando o mapa Array # semelhante à sugestão de Michael Deal, aqui está um tipo que eu uso para encontrar a versão mais recente de um semver padrão de 3 partes:
fonte