やりたいこと
- バージョン番号のようなドット区切り十進表記の文字列を比較したい。
- 一括比較したいだけなので、
System.Version
クラスを使ってまではやりたくない。
コード
自前実装
/// <summary>ドット区切り数字列を比較する</summary>
/// <param name="a">対象文字列A</param>
/// <param name="b">対象文字列B</param>
/// <param name="number">比較する列数 (0なら全て)</param>
/// <returns>A-Bの符号 (1, 0, -1)</returns>
public static int CompareVersionString (this string a, string b, int number = 0) {
var aSeries = a.Split ('.');
var bSeries = b.Split ('.');
int aNum, bNum;
number = (number > 0) ? Mathf.Min (number, aSeries.Length) : aSeries.Length;
for (var i = 0; i < number; i++) {
if (i >= bSeries.Length) { return 1; }
aNum = 0; int.TryParse (aSeries [i], out aNum);
bNum = 0; int.TryParse (bSeries [i], out bNum);
if (aNum > bNum) { return 1; } else if (aNum < bNum) { return -1; }
}
return (aSeries.Length == bSeries.Length) ? 0 : -1;
}
- Unity以外では、
Mathf
でなくMath
を使用してください。
蛇足
使用例
#if UNITY_*
Debug.Log ("1.1.12".CompareVersionString ("1.1.12.0"));
#else
Console.WriteLine ("1.1.12".CompareVersionString ("1.1.12.0"));
#endif
// -1
- 実際には
UNITY_*
という記述はできません。
Debug.Log ("1.1.12".CompareVersionString ("1.1.12.0", 3));
// 0
- 比較する列数を指定することができます。
仕様
- 以下の説明では、ドットで区切られた個々の数字列を"位"と称します。
- 一般に、"メジャー"、"マイナー"、"ビルド"、"リビジョン"などと呼ばれるもののことです。
- 各"位"を数値化するルールは、
int.TryParse ()
に準じます。- 数値化できなかった場合は
0
と見なします。
- 数値化できなかった場合は
- 双方の文字列の左端は、同じ大きさの"位"であるものと見なし、右に行くほど段階的に小さくなるものとします。
- 「左端は必ず"メジャー"で、次は"マイナー"である」ということです。
- "位"が存在しない場合は、
0
よりも"小さい"値と見なします。(上記の使用例を参照) - 比較の結果を、
(a < b) => -1
、(a == b) => 0
、(a > b) => 1
で返します。
参考
- Unityのインスペクタで設定される"Version*"文字列(Application.version)をマスタデータとして扱いたかったので、こういうやり方をしています。
- 通常は、素直にVersionクラスを使うことをお勧めします。