[解決済み】ソフトウェアのバージョン番号をjsで比較する方法は?(数字のみ)
質問
ソフトウェアのバージョン番号はこちらです。
"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"
これを比較するにはどうしたらいいでしょうか? 正しい順序を仮定してください。
"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"
考え方は簡単です...。 1桁目を読み、2桁目を読み、3桁目を読む......。 でも、バージョン番号を浮動小数点数に変換することができない......。 また、バージョン番号はこのように見ることができます。
"1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1.0"
と、このように、背後にあるアイデアが何であるかがより明確になっています。 しかし、これをどのようにコンピュータのプログラムに変換するのでしょうか? どなたか、この仕分け方法についてご存知の方はいらっしゃいますか?ありがとうございました。
どのように解決するのですか?
この比較を行うための基本的な考え方は
Array.split
を使って入力文字列から部品の配列を取得し、2つの配列の部品のペアを比較します。部品が等しくない場合は、どちらのバージョンが小さいかを知ることができます。
注意すべき点がいくつかあります。
- 各ペアのパーツはどのように比較すればよいのでしょうか?質問では数値で比較したいのですが、数字だけで構成されていないバージョン文字列(例:"1.0a")がある場合はどうすればよいでしょうか?
- 一方のバージョン文字列が他方より多くの部分を持つ場合、どうすればよいでしょうか。おそらく "1.0" は "1.0.1" よりも小さいと考えるべきですが、"1.0.0" はどうでしょうか?
以下は直接使える実装のコードです( ドキュメント付きリスト ):
function versionCompare(v1, v2, options) {
var lexicographical = options && options.lexicographical,
zeroExtend = options && options.zeroExtend,
v1parts = v1.split('.'),
v2parts = v2.split('.');
function isValidPart(x) {
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
}
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
return NaN;
}
if (zeroExtend) {
while (v1parts.length < v2parts.length) v1parts.push("0");
while (v2parts.length < v1parts.length) v2parts.push("0");
}
if (!lexicographical) {
v1parts = v1parts.map(Number);
v2parts = v2parts.map(Number);
}
for (var i = 0; i < v1parts.length; ++i) {
if (v2parts.length == i) {
return 1;
}
if (v1parts[i] == v2parts[i]) {
continue;
}
else if (v1parts[i] > v2parts[i]) {
return 1;
}
else {
return -1;
}
}
if (v1parts.length != v2parts.length) {
return -1;
}
return 0;
}
このバージョンではパーツを比較します 当然 また、"1.7" は "1.7.0" よりも小さいと見なします。比較モードを辞書式に変更したり、オプションの第3引数を用いて短いバージョンの文字列を自動的にゼロパディングしたりすることができます。
ユニットテストを実行するJSFiddleがあります。 こちら を少し拡張したものです。 ripper234さんの作品 (ありがとうございます)。
重要なお知らせです。
このコードでは
Array.map
と
Array.every
もし、これらのメソッドに対応する必要がある場合は、不足するメソッドのポリフィルを提供する必要があります。
関連
-
[解決済み】Vueのテンプレートまたはレンダー関数が定義されていない 私はどちらも使っていないのですが?
-
[解決済み】SyntaxError: 期待された式が、'<'を得た。
-
[解決済み] JavaScriptでカンマを桁区切りにして数値を表示する方法
-
[解決済み] Javascriptで文字列の最後の文字を切り取るにはどうしたらいいですか?
-
[解決済み] JavaScriptでオブジェクトのキー/プロパティの数を効率的にカウントする方法
-
[解決済み] jQueryを使用してハイパーリンクのhref属性を変更する方法
-
[解決済み] JavaScriptで浮動小数点数を整数に変換するには?
-
[解決済み] JavaScriptで配列を比較する方法は?
-
[解決済み] jQueryを使用してdivのinnerHTMLを置き換えるには?
-
[解決済み】固定長 6 int 配列の最速ソート
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】このエラーの原因は何ですか - "Fatal error: ローカルgruntを見つけることができません"
-
[解決済み] Uncaught TypeError: 未定義のプロパティ 'top' を読み込めない
-
[解決済み] Uncaught Invariant Violation: 前のレンダリング中よりも多くのフックをレンダリングした
-
[解決済み】未定義のプロパティ 'bind' を読み込めない。React.js【重複あり
-
[解決済み】Reactのeslintエラーはpropsの検証で見つからない
-
[解決済み】XMLパースエラー:ルート要素が見つからない コンソールの場所 FF
-
[解決済み】HTMLの最初の行に予期しないトークン<がある。
-
[解決済み】react router v^4.0.0 Uncaught TypeError: 未定義のプロパティ'location'を読み取れない
-
[解決済み] JavaScriptで浮動小数点数の精度を扱うには?
-
[解決済み】JavaScriptで2つの変数を入れ替える方法