如何获取最新或最大文件夹版本?
How to get a latest or max folder version?
我有一些版本文件夹,例如 Vx_x_x
我想检索最大文件夹版本。
例如:
文件夹包含,
V8_2_1
V9_3_2
V10_4_1
我想检查 V 旁边的最大数量等等以获得最新的文件夹版本。
我能够获取文件夹列表,但对如何获取最大数量感到困惑。如果有人可以建议我,我会很有帮助。谢谢你。
private static void GetFolderVersion()
{
string startFolder = @"C:\Version\";
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
IEnumerable<System.IO.DirectoryInfo> directoryList = dir.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
}
虽然这可能确实有效,但建议使用@jbartuszek 的解决方案,该解决方案使用 Version
class.
按照这些思路可以做到这一点,但请注意,这是我的想法,用记事本写成,因此可能不会构建或包含某种形式的逻辑错误。这只是说明了它的要点:
string[] version = folderName.Split('_');
string[] otherVersion = otherFolderName.Split('_');
然后您编写一个方法来检查版本的各个部分:
private int CompareVersions(string[] version, string[] otherVersion)
{
//we won't need the first character (the 'V')
int vmajor = int.Parse(version[0].Substring(1));
int vminor = int.Parse(version[1]);
int vrevision = int.Parse(version[2]);
int ovmajor = int.Parse(otherVersion[0].Substring(1));
int ovminor = int.Parse(otherVersion[1]);
int ovrevision = int.Parse(otherVersion[2]);
int majorCompare = vmajor.CompareTo(ovmajor);
//check if major already decides outcome
if(majorCompare != 0)
{
return majorCompare;
}
int minorCompare = vminor.CompareTo(ovminor);
//then if major equal, check if minor decides outcome
if(minorCompare != 0)
{
return minorCompare;
}
//lastly, return outcome of revision compare
return vrevision.CompareTo(ovrevision);
}
这就是您比较两个文件夹名称的方式。如果您想获得最大文件夹版本,您可以 foreach
文件夹名称:
//we'll start out by assigning the first folder name as a preliminary max
string maxFolder = folderNames[1];
string[] maxFolderVersion = maxFolder.Split('_');
foreach(string folderName in folderNames)
{
if(CompareVersions(folderName.Split('_'), maxFolderVersion) > 0)
{
maxFolder = folderName;
}
}
如果文件都符合您提供的模式,我很想使用正则表达式提取版本信息,然后选择最高值,从主要版本开始计算。
更新:用适合您的情况的正确前缀替换正则表达式中的 V。
var regex = new Regex(@"^V(\d+)_(\d+)_(\d+)$", RegexOptions.Compiled);
var versions = directoryList
.Select(f => regex.Match(f))
.Where(m => m.Success)
.Select(m => new
{
Major = Int32.Parse(m.Groups[1].Value),
Minor = Int32.Parse(m.Groups[2].Value),
Patch = Int32.Parse(m.Groups[3].Value)
}).ToList();
var major = versions.Max(a => a.Major);
versions = versions
.Where(a => a.Major == major)
.ToList();
var minor = versions.Max(a => a.Minor);
versions = versions
.Where(a => a.Minor == minor)
.ToList();
var patch = versions.Max(a => a.Patch);
versions = versions
.Where(a => a.Patch == patch)
.ToList();
var newest = versions.First();
var filename = String.Format("V_{0}_{1}_{2}", newest.Major, newest.Minor, newest.Patch);
我会考虑使用内置的 System.Version
类型。假设所有目录名称的格式都相同 "VX_Y_Z"(其中 X、Y 和 Z 代表一位或多位数字,V 代表文字 "V"),下面的代码将执行您想要的操作:
public string GetMaxVersion(IEnumerable<string> directoryNames)
{
var vDict = directoryNames.ToDictionary(
s => new Version(s.Substring(1).Replace("_", ".")),
s => s);
var maxKey = vDict.Keys.Max();
return vDict[maxKey];
}
这里我们构建一个版本字典到文件名映射(注意我们将字符串格式从 "VX_Y_Z" 更改为 "X.Y.Z" 以便能够创建一个 System.Version
对象)。剩下的就是检索所有字典键的最大值,以及 return 分配给给定键的值,这将是您要查找的目录名称。
更新: 为了完整起见,这里有一段代码使用了上面的方法并处理了所有事情:
public string GetMaxVersionDirectory(string rootDirectory)
{
var dirNames = Directory.GetDirectories(rootDirectory, "V*_*_*")
.Select(dir => Path.GetFileName(dir));
return GetMaxVersion(dirNames);
}
在您的情况下,您需要将 @"C:\Version"
作为 rootDirectory
参数传递。
您可以使用数学方法。假设您版本的每个部分都可以达到最大值。 1000。所以基数是 1000。版本部分是你的系数,指数是在你的循环中构建的。通过对 coefficent*base^exp 求和,您可以得到一个值,您可以比较该值以获得最高版本:
private static string GetHighestFolderVersion()
{
string startFolder = @"C:\Version\";
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
IEnumerable<System.IO.DirectoryInfo> directoryList = dir.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
KeyValuePair<string, long> highestVersion = new KeyValuePair<string, long>("", 0);
foreach (System.IO.DirectoryInfo dirInfo in directoryList)
{
string versionOrigName = dirInfo.Name;
string versionStr = versionOrigName.Substring(1);
List<string> versionParts = versionStr.Split('_').ToList<string>();
long versionVal = 0;
int exp = 0;
for (int i = versionParts.Count - 1; i > -1; i--)
{
versionVal += (long.Parse(versionParts[i]) * (long)(Math.Pow(1000, exp)));
exp++;
}
if (versionVal > highestVersion.Value)
{
highestVersion = new KeyValuePair<string, long>(versionOrigName, versionVal);
}
}
return highestVersion.Key;
}
我有一些版本文件夹,例如 Vx_x_x
我想检索最大文件夹版本。
例如:
文件夹包含,
V8_2_1
V9_3_2
V10_4_1
我想检查 V 旁边的最大数量等等以获得最新的文件夹版本。
我能够获取文件夹列表,但对如何获取最大数量感到困惑。如果有人可以建议我,我会很有帮助。谢谢你。
private static void GetFolderVersion()
{
string startFolder = @"C:\Version\";
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
IEnumerable<System.IO.DirectoryInfo> directoryList = dir.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
}
虽然这可能确实有效,但建议使用@jbartuszek 的解决方案,该解决方案使用 Version
class.
按照这些思路可以做到这一点,但请注意,这是我的想法,用记事本写成,因此可能不会构建或包含某种形式的逻辑错误。这只是说明了它的要点:
string[] version = folderName.Split('_');
string[] otherVersion = otherFolderName.Split('_');
然后您编写一个方法来检查版本的各个部分:
private int CompareVersions(string[] version, string[] otherVersion)
{
//we won't need the first character (the 'V')
int vmajor = int.Parse(version[0].Substring(1));
int vminor = int.Parse(version[1]);
int vrevision = int.Parse(version[2]);
int ovmajor = int.Parse(otherVersion[0].Substring(1));
int ovminor = int.Parse(otherVersion[1]);
int ovrevision = int.Parse(otherVersion[2]);
int majorCompare = vmajor.CompareTo(ovmajor);
//check if major already decides outcome
if(majorCompare != 0)
{
return majorCompare;
}
int minorCompare = vminor.CompareTo(ovminor);
//then if major equal, check if minor decides outcome
if(minorCompare != 0)
{
return minorCompare;
}
//lastly, return outcome of revision compare
return vrevision.CompareTo(ovrevision);
}
这就是您比较两个文件夹名称的方式。如果您想获得最大文件夹版本,您可以 foreach
文件夹名称:
//we'll start out by assigning the first folder name as a preliminary max
string maxFolder = folderNames[1];
string[] maxFolderVersion = maxFolder.Split('_');
foreach(string folderName in folderNames)
{
if(CompareVersions(folderName.Split('_'), maxFolderVersion) > 0)
{
maxFolder = folderName;
}
}
如果文件都符合您提供的模式,我很想使用正则表达式提取版本信息,然后选择最高值,从主要版本开始计算。
更新:用适合您的情况的正确前缀替换正则表达式中的 V。
var regex = new Regex(@"^V(\d+)_(\d+)_(\d+)$", RegexOptions.Compiled);
var versions = directoryList
.Select(f => regex.Match(f))
.Where(m => m.Success)
.Select(m => new
{
Major = Int32.Parse(m.Groups[1].Value),
Minor = Int32.Parse(m.Groups[2].Value),
Patch = Int32.Parse(m.Groups[3].Value)
}).ToList();
var major = versions.Max(a => a.Major);
versions = versions
.Where(a => a.Major == major)
.ToList();
var minor = versions.Max(a => a.Minor);
versions = versions
.Where(a => a.Minor == minor)
.ToList();
var patch = versions.Max(a => a.Patch);
versions = versions
.Where(a => a.Patch == patch)
.ToList();
var newest = versions.First();
var filename = String.Format("V_{0}_{1}_{2}", newest.Major, newest.Minor, newest.Patch);
我会考虑使用内置的 System.Version
类型。假设所有目录名称的格式都相同 "VX_Y_Z"(其中 X、Y 和 Z 代表一位或多位数字,V 代表文字 "V"),下面的代码将执行您想要的操作:
public string GetMaxVersion(IEnumerable<string> directoryNames)
{
var vDict = directoryNames.ToDictionary(
s => new Version(s.Substring(1).Replace("_", ".")),
s => s);
var maxKey = vDict.Keys.Max();
return vDict[maxKey];
}
这里我们构建一个版本字典到文件名映射(注意我们将字符串格式从 "VX_Y_Z" 更改为 "X.Y.Z" 以便能够创建一个 System.Version
对象)。剩下的就是检索所有字典键的最大值,以及 return 分配给给定键的值,这将是您要查找的目录名称。
更新: 为了完整起见,这里有一段代码使用了上面的方法并处理了所有事情:
public string GetMaxVersionDirectory(string rootDirectory)
{
var dirNames = Directory.GetDirectories(rootDirectory, "V*_*_*")
.Select(dir => Path.GetFileName(dir));
return GetMaxVersion(dirNames);
}
在您的情况下,您需要将 @"C:\Version"
作为 rootDirectory
参数传递。
您可以使用数学方法。假设您版本的每个部分都可以达到最大值。 1000。所以基数是 1000。版本部分是你的系数,指数是在你的循环中构建的。通过对 coefficent*base^exp 求和,您可以得到一个值,您可以比较该值以获得最高版本:
private static string GetHighestFolderVersion()
{
string startFolder = @"C:\Version\";
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
IEnumerable<System.IO.DirectoryInfo> directoryList = dir.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
KeyValuePair<string, long> highestVersion = new KeyValuePair<string, long>("", 0);
foreach (System.IO.DirectoryInfo dirInfo in directoryList)
{
string versionOrigName = dirInfo.Name;
string versionStr = versionOrigName.Substring(1);
List<string> versionParts = versionStr.Split('_').ToList<string>();
long versionVal = 0;
int exp = 0;
for (int i = versionParts.Count - 1; i > -1; i--)
{
versionVal += (long.Parse(versionParts[i]) * (long)(Math.Pow(1000, exp)));
exp++;
}
if (versionVal > highestVersion.Value)
{
highestVersion = new KeyValuePair<string, long>(versionOrigName, versionVal);
}
}
return highestVersion.Key;
}