C# 在目录c中搜索最新更新#
我有一个名为Updates的目录,里面有许多名为Update10、Update15、Update13等文件夹。 我需要能够通过比较文件夹名称上的数字获得最新更新,并返回该文件夹的路径。 任何帮助都将受到限制您可以使用LINQ:C# 在目录c中搜索最新更新#,c#,linq,updates,C#,Linq,Updates,我有一个名为Updates的目录,里面有许多名为Update10、Update15、Update13等文件夹。 我需要能够通过比较文件夹名称上的数字获得最新更新,并返回该文件夹的路径。 任何帮助都将受到限制您可以使用LINQ: int updateInt = 0; var mostRecendUpdate = Directory.EnumerateDirectories(updateDir) .Select(path => new { fullPath =
int updateInt = 0;
var mostRecendUpdate = Directory.EnumerateDirectories(updateDir)
.Select(path => new
{
fullPath = path,
directoryName = System.IO.Path.GetFileName(path) // returns f.e. Update15
})
.Where(x => x.directoryName.StartsWith("Update")) // precheck
.Select(x => new
{
x.fullPath, x.directoryName,
updStr = x.directoryName.Substring("Update".Length) // returns f.e. "15"
})
.Where(x => int.TryParse(x.updStr, out updateInt)) // int-check and initialization of updateInt
.Select(x => new { x.fullPath, x.directoryName, update = updateInt })
.OrderByDescending(x => x.update) // main task: sorting
.FirstOrDefault(); // return newest update-infos
if(mostRecendUpdate != null)
{
string fullPath = mostRecendUpdate.fullPath;
int update = mostRecendUpdate.update;
}
A使用一个返回int?
的方法,而不是使用局部变量作为out参数,因为LINQ不应该引起这样的副作用。它们可能是有害的
注意:当前查询区分大小写,它不会将UPDATE11
识别为有效目录。如果要比较不区分大小写,必须使用适当的StartsWith
重载:
.....
.Where(x => x.directoryName.StartsWith("Update", StringComparison.InvariantCultureIgnoreCase)) // precheck
.....
最好的方法是使用有问题的评论所建议的修改日期。 不过,要将字符串排序为数字,可以使用IComparer。 这项工作已经完成,可以在中找到 用样本编辑 获取目录后:
string[] dirs = System.IO.Directory.GetDirectories();
var numComp = new NumericComparer();
Array.Sort(dirs, numComp);
目录中的最后一项是您最后一次“修改”的目录。此函数使用LINQ获取最后一次更新的目录路径
public string GetLatestUpdate(string path)
{
if (!path.EndsWith("\\")) path += "\\";
return System.IO.Directory.GetDirectories(path)
.Select(f => new KeyValuePair<string, long>(f, long.Parse(f.Remove(0, (path + "Update").Length))))
.OrderByDescending(kvp => kvp.Value)
.First().Key;
}
公共字符串GetLatestUpdate(字符串路径)
{
如果(!path.EndsWith(“\\”)路径+=“\\”;
返回System.IO.Directory.GetDirectories(路径)
.Select(f=>newkeyvaluepair(f,long.Parse(f.Remove(0,(path+“Update”).Length)))
.OrderByDescending(kvp=>kvp.Value)
.First()键;
}
如果您可以依赖文件夹的创建日期,您可以通过使用以下工具来简化此过程:
作为参考,MaxBy()
的一个实现是:
public static class EnumerableMaxMinExt
{
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
return source.MaxBy(selector, Comparer<TKey>.Default);
}
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
throw new InvalidOperationException("Sequence was empty");
}
TSource max = sourceIterator.Current;
TKey maxKey = selector(max);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, maxKey) > 0)
{
max = candidate;
maxKey = candidateProjected;
}
}
return max;
}
}
}
公共静态类EnumerableMaxMinExt
{
公共静态TSource MaxBy(此IEnumerable源,Func选择器)
{
返回source.MaxBy(选择器、比较器、默认值);
}
公共静态TSource MaxBy(此IEnumerable源、Func选择器、IComparer比较器)
{
使用(IEnumerator sourceIterator=source.GetEnumerator())
{
如果(!sourceIterator.MoveNext())
{
抛出新的InvalidOperationException(“序列为空”);
}
TSource max=sourceIterator.Current;
TKey maxKey=选择器(最大值);
while(sourceIterator.MoveNext())
{
TSource candidate=sourceIterator.Current;
TKey candidateProjected=选择器(候选者);
if(comparer.Compare(candidateProjected,maxKey)>0)
{
max=候选人;
maxKey=候选项目;
}
}
返回最大值;
}
}
}
每个文件夹都以“更新”一词开头,后跟一个或多个数字?更高的数字是最新的?创建/修改的日期不应该更准确吗?我相信你可以试一试。发布您尝试过的内容,这意味着编号会变为Update1
,Update2
,…,Update9
,Update10
,从而阻止任何直接按名称排序的尝试1.每个文件夹都将以“更新”2开头。我不能相信日期,3。我尝试过使用linq,但无法理解语法,4。最高的数字确实是最新的更新yesI不能使用日期:\
public static class EnumerableMaxMinExt
{
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
return source.MaxBy(selector, Comparer<TKey>.Default);
}
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
throw new InvalidOperationException("Sequence was empty");
}
TSource max = sourceIterator.Current;
TKey maxKey = selector(max);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, maxKey) > 0)
{
max = candidate;
maxKey = candidateProjected;
}
}
return max;
}
}
}