JavaScriptでバージョン文字列を比較します

こんにちは、さるまりんです。

ソフトウェアやサービスのバージョン番号、13.6.7のような文字列で表されることがあります。
数字を.で区切った文字列です。
これを元に処理を分けたい、例えば、13.5以上だったら、未満だったらと処理を分岐させたい時があります。

これの大小を比較したいです。文字列も><==等、比較演算子で比較できるのですが、これだと問題が起きます。

例えば1.101.9を比較すると、1.10の方が大きくなってほしいのですが、文字列として比較すると1.9の方が大きいと判断されてしまいます。なので関数を書いて対応します。

前提ですが、バージョン番号には0.1.0-SNAPSHOTとか1.3rcとか数字以外を含む場合もありますが今回はそれはスルーさせてもらっています。

JavaScriptで関数を書くとこんな感じになります。

function compareVersionStrings(version1, version2) {
    // それぞれの文字列を分割します。
    const parts1 = version1.split('.').map(Number);
    const parts2 = version2.split('.').map(Number);

    const maxLength = Math.max(parts1.length, parts2.length);

    // 分割されたパーツ毎に比較します
    for (let i = 0; i < maxLength; i++) {
        // パーツがない場合は0とします
        const part1 = parts1[i] || 0;
        const part2 = parts2[i] || 0;

        // version1の方が小さければ-1を、version1の方が大きければ1を返します
        if (part1 < part2) {
            return -1;
        } else if (part1 > part2) {
            return 1;
        }
    }

    // ここまできたら同じなので0を返します
    return 0;
}

compareVersionStrings()version1version2より小さければ-1、大きければ1、同じならば0を返します。
コメントも書いていますが分割した部分を数値として比較してどちらが大きいかで結果を返すようにしています。
文字列を分割するとそれぞれ文字列になるのですが、map(Number)で数値にしています。
ちなみにmap(s => parseInt(s, 10))としたら整数値になります。
が、今回は.で分割しているので小数点を含む数字にならないので結果には影響しないと思います。

実行すると結果は↓です。

compareVersionStrings("5.3.2", "5.3.10")-1
compareVersionStrings("5.3.1", "5.3") → 1
compareVersionStrings("5.3.1", "5.3.1") → 0

Webページ上でUserAgentのバージョンで処理を切り分けるというのは度々出てきます。
その時に使えるかなと思うのでここに残しておきます。
他の言語にも簡単に直せそうですね。

読んでくださってありがとうございました。
それではまた!