C# i比较问题+;如何在.NET中对字符串数组进行自然排序(FILE_10>;FILE_2)?
在我的帖子底部解决了这个问题 或者更具体地说: 我有一堆FileInfo对象(我需要FileInfo对象来排除隐藏的、系统的和重新分析的点文件) 我需要根据FileInfo.FullName对FileInfo[]进行自然排序。所以文件_10.ext应该在文件_2.ext之后。幸运的是,FileInfo[]只包含一个扩展名的文件 我已经实现了一个比较器:C# i比较问题+;如何在.NET中对字符串数组进行自然排序(FILE_10>;FILE_2)?,c#,arrays,sorting,icomparer,natural-sort,C#,Arrays,Sorting,Icomparer,Natural Sort,在我的帖子底部解决了这个问题 或者更具体地说: 我有一堆FileInfo对象(我需要FileInfo对象来排除隐藏的、系统的和重新分析的点文件) 我需要根据FileInfo.FullName对FileInfo[]进行自然排序。所以文件_10.ext应该在文件_2.ext之后。幸运的是,FileInfo[]只包含一个扩展名的文件 我已经实现了一个比较器: /// <summary> /// Compares FileInfo objects based on the files ful
/// <summary>
/// Compares FileInfo objects based on the files full path.
/// This comparer is flawed in that it will only work correctly
/// on files with the same extension.
/// Though that could easily be fixed.
/// </summary>
private class FileInfoSorter : IComparer
{
int IComparer.Compare(Object x, Object y)
{
FileInfo _x = x as FileInfo;
FileInfo _y = y as FileInfo;
// FYI:
//ExprFileVersion = new Regex("(.*)_([0-9]+)\\.[^\\.]+$", RegexOptions.Compiled);
Match m1 = RegExps.ExprFileVersion.Match(_x.FullName);
Match m2 = RegExps.ExprFileVersion.Match(_y.FullName);
if (m1.Success && m2.Success) // we have versioned files
{
int n1;
int n2;
try
{
n1 = int.Parse(m1.Groups[2].Value);
}
catch (OverflowException ex)
{
// Don't know if this works.
ex.Data["File"] = _x.FullName;
throw;
}
try
{
n2 = int.Parse(m2.Groups[2].Value);
}
catch (OverflowException ex)
{
// Don't know if this works.
ex.Data["File"] = _y.FullName;
throw;
}
string s1 = m1.Groups[1].Value;
string s2 = m2.Groups[1].Value;
if (s1.Equals(s2))
{
return n1.CompareTo(n2); // compare numbers naturally. E.g. 11 > 6
}
else // not the same base file name. So the version does not matter.
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
else // not versioned
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
}
EDIT1:Int.Parse遇到太大的数字时抛出OverflowException。这不应该定期发生,但我希望它得到保障
编辑2:我最后调整了自己的比较器。不再使用int.Parse,只使用0填充以进行比较。
代码如下:
public class FileInfoSorter : IComparer
{
int IComparer.Compare(Object x, Object y)
{
FileInfo _x = x as FileInfo;
FileInfo _y = y as FileInfo;
Match m1 = RegExps.ExprFileVersion.Match(_x.FullName);
Match m2 = RegExps.ExprFileVersion.Match(_y.FullName);
if (m1.Success && m2.Success) // we have versioned files
{
string n1;
string n2;
n1 = m1.Groups[2].Value;
n2 = m2.Groups[2].Value;
string s1 = m1.Groups[1].Value;
string s2 = m2.Groups[1].Value;
int max = Math.Max(n1.Length, n2.Length);
n1 = n1.PadLeft(max, '0');
n2 = n2.PadLeft(max, '0');
if (s1.Equals(s2)) // we have to compare the version
// which is now left-padded with 0s.
{
return ((new CaseInsensitiveComparer()).Compare(n1, n2));
}
else // not the same base file name. So the version does not matter.
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
else // not versioned
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
}
是的,有。这个问题已经得到了回答。您基本上希望通过P/Invoke层调用函数。有关详细信息,请参见原始答案:
我不喜欢p/Invoke。它总是让我觉得这是某种黑客行为;)非常感谢。我会调查一下的。对我的异常问题有什么想法吗?再次感谢你。我最终实现了自己的工作分类器。
public class FileInfoSorter : IComparer
{
int IComparer.Compare(Object x, Object y)
{
FileInfo _x = x as FileInfo;
FileInfo _y = y as FileInfo;
Match m1 = RegExps.ExprFileVersion.Match(_x.FullName);
Match m2 = RegExps.ExprFileVersion.Match(_y.FullName);
if (m1.Success && m2.Success) // we have versioned files
{
string n1;
string n2;
n1 = m1.Groups[2].Value;
n2 = m2.Groups[2].Value;
string s1 = m1.Groups[1].Value;
string s2 = m2.Groups[1].Value;
int max = Math.Max(n1.Length, n2.Length);
n1 = n1.PadLeft(max, '0');
n2 = n2.PadLeft(max, '0');
if (s1.Equals(s2)) // we have to compare the version
// which is now left-padded with 0s.
{
return ((new CaseInsensitiveComparer()).Compare(n1, n2));
}
else // not the same base file name. So the version does not matter.
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
else // not versioned
{
return ((new CaseInsensitiveComparer()).Compare(_x.FullName, _y.FullName));
}
}
}