Oto numer wersji oprogramowania:
"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"
Jak mogę to porównać? Załóżmy, że prawidłowa kolejność to:
"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"
Pomysł jest prosty ...: Przeczytaj pierwszą cyfrę, potem drugą, potem trzecią .... Ale nie mogę przekonwertować numeru wersji na liczbę zmiennoprzecinkową .... Możesz również zobaczyć numer wersji, taki jak to:
"1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1.0"
i to jest bardziej jasne, aby zobaczyć, jaki jest pomysł ... Ale jak przekonwertować go na program komputerowy? Czy ktoś ma pomysł, jak to posortować? Dziękuję Ci.
javascript
sorting
Tattat
źródło
źródło
Odpowiedzi:
Podstawowym pomysłem wykonania tego porównania byłoby użycie
Array.split
tablic części z łańcuchów wejściowych, a następnie porównanie par części z dwóch tablic; jeśli części nie są równe, wiemy, która wersja jest mniejsza.Należy pamiętać o kilku ważnych szczegółach:
Oto kod implementacji, którego możesz użyć bezpośrednio ( streszczenie z dokumentacją ):
Ta wersja w naturalny sposób porównuje części , nie akceptuje przyrostków znaków i uważa, że „1.7” jest mniejsze niż „1.7.0”. Tryb porównania można zmienić na leksykograficzny, a krótsze ciągi wersji mogą być automatycznie uzupełniane zerami przy użyciu opcjonalnego trzeciego argumentu.
Jest JSFiddle który działa „testy jednostkowe” tutaj ; jest to nieco rozbudowana wersja pracy ripper234 (dziękuję).
Ważna uwaga: ten kod używa
Array.map
iArray.every
, co oznacza, że nie będzie działał w wersjach IE wcześniejszych niż 9. Jeśli chcesz je obsługiwać, będziesz musiał dostarczyć polifill dla brakujących metod.źródło
semver
Parser wersji semantycznej używany przez npm.
$ npm zainstaluj semver
Łącze do wersjonowania semantycznego :
https://www.npmjs.com/package/semver#prerelease-identifiers
źródło
źródło
var len = Math.min(a_components.length, b_components.length);
spowoduje, że wersje 2.0.1.1 i 2.0.1 będą traktowane tak samo, czy to prawda?a = '7'
ib = '7.0'
wraca,-1
ponieważ wersja 7.0 jest dłuższa. Masz jakąś sugestię? (console.log(compare("7", "7.0")); //returns -1
)Ta bardzo mała, ale bardzo szybka funkcja porównywania przyjmuje numery wersji o dowolnej długości i dowolnej wielkości liczbowej na segment .
Wartości zwracane:
- liczba,
< 0
jeśli a <b- liczba,
> 0
jeśli a> b-
0
jeśli a = bMożesz więc użyć go jako funkcji porównawczej dla Array.sort ();
EDYCJA: Usunięto błędy w wersji usuwającej końcowe zera, aby rozpoznawać „1” i „1.0.0” jako równe
źródło
["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"]
gdzie wyprowadza twój kod["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"]
, co jest całkowicie takie samo, ponieważ 0,0 i 0,0.0 są uważane za równe , co oznacza, że nie ma znaczenia, czy „0,0” jest przed „0,0,0”, czy odwrotnie.Zrobiono z http://java.com/js/deployJava.js :
źródło
Nie udało się znaleźć funkcji, która spełniałaby moje oczekiwania. Więc napisałem własne. To mój wkład. Mam nadzieję, że ktoś uzna to za przydatne.
Plusy:
Obsługuje ciągi wersji o dowolnej długości. „1” lub „1.1.1.1.1”.
Domyślnie każda wartość wynosi 0, jeśli nie zostanie określona. To, że sznurek jest dłuższy, nie oznacza, że jest to większa wersja. („1” powinno być tym samym, co „1.0” i „1.0.0.0”).
Porównaj liczby, a nie ciągi. („3” <„21” powinno być prawdą. Nie fałszem).
Nie trać czasu na bezużyteczne porównania w pętli. (Porównanie dla ==)
Możesz wybrać własny komparator.
Cons:
Mój kod, podobny do zaakceptowanej odpowiedzi Jona :
Przykłady :
źródło
Prosta i krótka funkcja:
Testy:
źródło
Wybacz mi, jeśli ten pomysł był już odwiedzony w linku, którego nie widziałem.
Odniosłem pewien sukces przy zamianie części na sumę ważoną, taką jak:
Co sprawiło, że porównania były bardzo łatwe (porównywanie podwójnego). Nasze pola wersji nigdy nie mają więcej niż 4 cyfry.
Mam nadzieję, że to komuś pomoże, ponieważ wiele warunków wydaje się nieco przesadzone.
źródło
Oto kolejna krótka wersja, która działa z dowolną liczbą podwersji, wypełnionych zer, a nawet cyfr z literami (1.0.0b3)
Wynik:
0 : a = b
1 : a> b
-1 : a <b
Pokaż fragment kodu
https://jsfiddle.net/vanowm/p7uvtbor/
źródło
Odpowiedź 2017:
Najprostszy kod dla nowoczesnych przeglądarek:
Chodzi o to, aby porównać liczby, ale w formie ciągu. aby porównanie działało, dwa struny muszą być tej samej długości. więc:
"123" > "99"
staje się"123" > "099"
wypełnieniem krótkiej liczby "napraw" porównanie
Tutaj dopełniam każdą część zerami do długości 10., a następnie po prostu używam prostego porównania ciągów do odpowiedzi
Przykład:
źródło
compareVersion2
co dokładnie się stało?substring
zamiastpadStart
dla lepszej kompatybilności tjvar zeros = "0000000000"; '0.2.32'.split('.').map( s => zeros.substring(0, zeros.length-s.length) + s ).join('.')
da wam0000000000.0000000002.0000000032
:)Sprawdzić działanie
version_compare()
od projektu php.js . Jest podobny do PHPversion_compare()
.Możesz go po prostu użyć w ten sposób:
źródło
Moja mniej szczegółowa odpowiedź niż większość odpowiedzi tutaj
źródło
Chociaż to pytanie ma już wiele odpowiedzi, każde z nich promuje swoje własne rozwiązanie, podczas gdy mamy do tego cały ekosystem (w bitwach) przetestowanych bibliotek.
Szybkie wyszukiwanie w NPM , GitHub , X da nam kilka uroczych bibliotek i chciałbym przejrzeć niektóre:
semver-compare
Jest to świetny lekki (~ 230B) lib to szczególnie przydatne, jeśli chcesz, aby posortować według numerów wersji, jako narażonych zwrotów metoda biblioteki-1
,0
lub1
odpowiednio.Rdzeń biblioteki:
compare-semver
ma dość spory rozmiar (~ 4,4kB spakowane gzipem), ale pozwala na kilka ładnych, unikalnych porównań, takich jak znalezienie min / max stosu wersji lub sprawdzenie, czy dostarczona wersja jest unikalna lub mniejsza niż cokolwiek innego w kolekcji wersje.compare-versions
to kolejna mała biblioteka (~ 630B spakowana gzipem) i ładnie podąża za specyfikacją, co oznacza, że możesz porównać wersje z flagami alfa / beta, a nawet z symbolami wieloznacznymi (jak dla wersji pomocniczych / łatek:1.0.x
lub1.0.*
)Chodzi o to: nie zawsze istnieje potrzeba kopiowania i wklejania kodu ze StackOverflow, jeśli możesz znaleźć przyzwoite, przetestowane (jednostkowo) wersje za pośrednictwem wybranego menedżera pakietów.
źródło
Zmierzyłem się z podobnym problemem i już stworzyłem na to rozwiązanie. Zapraszam do spróbowania.
Wraca
0
poequal
,1
jeśli wersja jestgreater
i-1
jeśli jestless
źródło
Chodzi o to, aby porównać dwie wersje i wiedzieć, która jest największa. Usuwamy „.” i porównujemy każdą pozycję wektora z innymi.
źródło
źródło
replace()
Funkcja zastąpi tylko pierwsze wystąpienie w ciągu. Tak, pozwala zastąpić.
z,
. Potem usunąć wszystko.
i zrobić,
aby.
ponownie i analizować je do pływaka.na koniec posortuj to:
źródło
Sprawdź ten wpis na blogu . Ta funkcja działa dla numerycznych numerów wersji.
źródło
Jeśli, na przykład, chcemy sprawdzić, czy aktualna wersja jQuery jest niższa niż 1.8,
parseFloat($.ui.version) < 1.8 )
dałoby to błędny wynik, jeśli wersja to "1.10.1", ponieważ zwraca parseFloat ("1.10.1")1.1
. Porównanie ciągów również by się nie udało, ponieważ"1.8" < "1.10"
wartościowane są dofalse
.Więc potrzebujemy takiego testu
Następująca funkcja obsługuje to poprawnie:
Oto kilka przykładów:
Zobacz tutaj próbkę na żywo i zestaw testów: http://jsfiddle.net/mar10/8KjvP/
źródło
Oto implementacja Coffeescript odpowiednia do użycia z Array.sort inspirowana innymi odpowiedziami tutaj:
źródło
Napisałem moduł node do sortowania wersji, możesz go znaleźć tutaj: version-sort
Cechy :
Nie wahaj się otworzyć problemu, jeśli potrzebujesz innej funkcji.
źródło
Działa to w przypadku wersji numerycznych o dowolnej długości oddzielonych kropką. Zwraca wartość true tylko wtedy, gdy myVersion jest> = minimumVersion, przy założeniu, że wersja 1 jest mniejsza niż 1.0, wersja 1.1 jest mniejsza niż 1.1.0 i tak dalej. Powinno być dość proste, aby dodać dodatkowe warunki, takie jak akceptowanie liczb (po prostu przekonwertowanie na ciąg) i szesnastkowe lub dynamiczne wprowadzanie separatora (wystarczy dodać parametr delimiter, a następnie zastąpić „.” Parametrem).
Oto kilka testów:
Alternatywnie tutaj jest wersja rekurencyjna
źródło
Znajduję najprostszy sposób na ich porównanie, nie jestem pewien, czy tego chcesz. kiedy uruchomię poniższy kod w konsoli, ma to sens, a używając metody sort (), mogłem uzyskać posortowaną tablicę ciągów wersji. jest oparty na porządku alfabetycznym.
źródło
Możesz użyć
String#localeCompare
zoptions
źródło
undefined
powyżej, język? Jak to się stało, że udaje ci się to opublikować, a ja czytam inne;)undefined
to część dotycząca ustawień regionalnych, nie jest tutaj używana.czy nie możesz zamienić ich na liczby, a następnie posortować według rozmiaru? Dołącz 0 do jedynek do liczb o długości mniejszej niż 4
grane w konsoli:
większa wersja, większa liczba. Edycja: prawdopodobnie wymaga dostosowania, aby uwzględnić większą serię wersji
źródło
To niezła sztuczka. Jeśli masz do czynienia z wartościami liczbowymi z określonego zakresu wartości, możesz przypisać wartość do każdego poziomu obiektu wersji. Na przykład „największa wartość” jest tutaj ustawiana na 0xFF, co tworzy bardzo podobny wygląd „IP” do wersjonowania.
Obsługuje również wersje alfanumeryczne (tj. 1,2a <1,2b)
źródło
Podoba mi się wersja z @ mar10 , chociaż z mojego punktu widzenia jest szansa na niewłaściwe użycie (wydaje się, że nie ma to miejsca, jeśli wersje są kompatybilne z dokumentem wersjonowania semantycznego , ale może się zdarzyć, jeśli zostanie użyty jakiś "numer kompilacji" ):
Problem polega na tym, że podliczby numeru wersji są w niektórych przypadkach zapisywane z wyciętymi końcowymi zerami (przynajmniej tak, jak widzę to ostatnio podczas korzystania z innego oprogramowania), co jest podobne do racjonalnej części liczby, więc:
Pierwsza (lub zarówno pierwsza, jak i druga) liczba podrzędna wersji jest jednak zawsze traktowana jako liczba całkowita, której faktycznie jest równa.
Jeśli używasz tego rodzaju wersjonowania, możesz zmienić tylko kilka wierszy w przykładzie:
Więc każdy sub-number wyjątkiem pierwszego będzie porównywany jako pływaka, tak
09
i1
będzie0.09
, a0.1
odpowiednio i porównywane prawidłowo w ten sposób.2054
i3
stanie się0.2054
i0.3
.Pełna wersja to (kredyty dla @ mar10 ):
PS Jest wolniej, ale można też pomyśleć o ponownym użyciu tej samej funkcji porównującej operującej faktem, że łańcuch jest w rzeczywistości tablicą znaków:
źródło
Zrobiłem to na podstawie pomysłu Konsola i zoptymalizowałem dla wersji Java "1.7.0_45". Jest to po prostu funkcja przeznaczona do konwersji ciągu wersji na wartość zmiennoprzecinkową. To jest funkcja:
Ciąg „1.7.0_45” jest konwertowany na 1,0070000450000001 i jest to wystarczające do normalnego porównania. Błąd wyjaśniony tutaj: Jak radzić sobie z precyzją liczb zmiennoprzecinkowych w JavaScript? . Jeśli potrzebujesz więcej niż 3 cyfr w dowolnej części, możesz zmienić separator
Math.pow(10, i * 3);
.Wynik będzie wyglądał następująco:
źródło
Miałem ten sam problem z porównaniem wersji, ale z wersjami mogącymi zawierać cokolwiek (tj: separatory, które nie były kropkami, rozszerzenia takie jak rc1, rc2 ...).
Użyłem tego, co w zasadzie podzieliło ciągi wersji na liczby i nieliczby, i próbuje porównać odpowiednio do typu.
W niektórych przypadkach istnieją pewne założenia, na przykład: „1,01” === „1,1” lub „1,8” <„1,71”. Nie radzi sobie z „1.0.0-rc.1” <„1.0.0”, jak określono w Semantic versionning 2.0.0
źródło
Wstępne przetwarzanie wersji przed sortowaniem oznacza, że parseInt nie jest wywoływana wiele razy niepotrzebnie. Używając mapy Array # podobnej do sugestii Michaela Deala, oto rodzaj, którego używam, aby znaleźć najnowszą wersję standardowego 3-częściowego semvera:
źródło