質問
これは私のコードです。「1、5、0、4」または「1.5.0.4」の形式で 2 つのバージョン識別子を受け取り、どちらが新しいバージョンであるかを判断します。
提案や改善点がありましたらお願いします。
/// <summary>
/// Compares two specified version strings and returns an integer that
/// indicates their relationship to one another in the sort order.
/// </summary>
/// <param name="strA">the first version</param>
/// <param name="strB">the second version</param>
/// <returns>less than zero if strA is less than strB, equal to zero if
/// strA equals strB, and greater than zero if strA is greater than strB</returns>
public static int CompareVersions(string strA, string strB)
{
char[] splitTokens = new char[] {'.', ','};
string[] strAsplit = strA.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
string[] strBsplit = strB.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
int[] versionA = new int[4];
int[] versionB = new int[4];
for (int i = 0; i < 4; i++)
{
versionA[i] = Convert.ToInt32(strAsplit[i]);
versionB[i] = Convert.ToInt32(strBsplit[i]);
}
// now that we have parsed the input strings, compare them
return RecursiveCompareArrays(versionA, versionB, 0);
}
/// <summary>
/// Recursive function for comparing arrays, 0-index is highest priority
/// </summary>
private static int RecursiveCompareArrays(int[] versionA, int[] versionB, int idx)
{
if (versionA[idx] < versionB[idx])
return -1;
else if (versionA[idx] > versionB[idx])
return 1;
else
{
Debug.Assert(versionA[idx] == versionB[idx]);
if (idx == versionA.Length - 1)
return 0;
else
return RecursiveCompareArrays(versionA, versionB, idx + 1);
}
}
@ ダレン・コップ:
version クラスは、形式 1.0.0.5 のバージョンを処理しません。
解決
の システム.バージョン クラスはカンマを含むバージョンをサポートしていないため、次の解決策が提示されます。 ダレン・コップ では不十分です。
ここでは、できるだけ単純なバージョンを示します (ただし、これ以上単純ではありません)。
それは使用しています システム.バージョン ただし、比較する前に検索置換を行うことで、「1、2、3、4」などのバージョン番号との互換性を実現します。
/// <summary>
/// Compare versions of form "1,2,3,4" or "1.2.3.4". Throws FormatException
/// in case of invalid version.
/// </summary>
/// <param name="strA">the first version</param>
/// <param name="strB">the second version</param>
/// <returns>less than zero if strA is less than strB, equal to zero if
/// strA equals strB, and greater than zero if strA is greater than strB</returns>
public static int CompareVersions(String strA, String strB)
{
Version vA = new Version(strA.Replace(",", "."));
Version vB = new Version(strB.Replace(",", "."));
return vA.CompareTo(vB);
}
コードは以下でテストされています。
static void Main(string[] args)
{
Test("1.0.0.0", "1.0.0.1", -1);
Test("1.0.0.1", "1.0.0.0", 1);
Test("1.0.0.0", "1.0.0.0", 0);
Test("1, 0.0.0", "1.0.0.0", 0);
Test("9, 5, 1, 44", "3.4.5.6", 1);
Test("1, 5, 1, 44", "3.4.5.6", -1);
Test("6,5,4,3", "6.5.4.3", 0);
try
{
CompareVersions("2, 3, 4 - 4", "1,2,3,4");
Console.WriteLine("Exception should have been thrown");
}
catch (FormatException e)
{
Console.WriteLine("Got exception as expected.");
}
Console.ReadLine();
}
private static void Test(string lhs, string rhs, int expected)
{
int result = CompareVersions(lhs, rhs);
Console.WriteLine("Test(\"" + lhs + "\", \"" + rhs + "\", " + expected +
(result.Equals(expected) ? " succeeded." : " failed."));
}
他のヒント
使用 バージョン クラス。
Version a = new Version("1.0.0.0");
Version b = new Version("2.0.0.0");
Console.WriteLine(string.Format("Newer: {0}", (a > b) ? "a" : "b"));
// prints b
まあ、要素が 4 つの配列しかないので、時間を節約するために再帰を展開したくないだけかもしれません。配列を引数として渡すとメモリが消費され、後で GC がクリーンアップするのに混乱が残ります。
バージョン文字列の各場所が 1 つの数字 (または少なくとも最後の 3 つ) だけであると仮定できる場合は、カンマまたはピリオドを削除して比較するだけで済みます...これははるかに高速になります...それほど堅牢ではありませんが、しかし、常にそれが必要なわけではありません。
public static int CompareVersions(string strA, string strB)
{
char[] splitTokens = new char[] {'.', ','};
string[] strAsplit = strA.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
string[] strBsplit = strB.Split(splitTokens, StringSplitOptions.RemoveEmptyEntries);
int versionA = 0;
int versionB = 0;
string vA = string.Empty;
string vB = string.Empty;
for (int i = 0; i < 4; i++)
{
vA += strAsplit[i];
vB += strBsplit[i];
versionA[i] = Convert.ToInt32(strAsplit[i]);
versionB[i] = Convert.ToInt32(strBsplit[i]);
}
versionA = Convert.ToInt32(vA);
versionB = Convert.ToInt32(vB);
if(vA > vB)
return 1;
else if(vA < vB)
return -1;
else
return 0; //they are equal
}
そして、はい、ここでは 4 つのバージョンの場所も想定しています...
所属していません StackOverflow