我在目录中有文件
0-0.jpeg
0-1.jpeg
0-5.jpeg
0-9.jpeg
0-10.jpeg
0-12.jpeg
...
当我加载文件时:
FileInfo[] files = di.GetFiles();
他们的订单错误(他们应该如上所述):
0-0.jpeg
0-1.jpeg
0-10.jpeg
0-12.jpeg
0-5.jpeg
0-9.jpeg
如何解决这个问题?
我试图对它们进行排序,但没办法:
1) Array.Sort(files, (f1, f2) => f1.Name.CompareTo(f2.Name));
2) Array.Sort(files, (x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.Name, y.Name));
答案 0 :(得分:6)
按字母顺序排列,“错误”的订单实际上是正确的。如果你想要按数字排序,那么你需要:
请参阅Sorting Directory.GetFiles()的答案,了解#3的例子。
答案 1 :(得分:5)
请参阅“CustomSort”功能here。
List<string> list = new List<string>() {
"0-5.jpeg",
"0-9.jpeg",
"0-0.jpeg",
"0-1.jpeg",
"0-10.jpeg",
"0-12.jpeg"};
list.CustomSort().ToList().ForEach(x => Console.WriteLine(x));
其输出:
0-0.jpeg
0-1.jpeg
0-5.jpeg
0-9.jpeg
0-10.jpeg
0-12.jpeg
答案 2 :(得分:4)
要解决此问题,您可以使用 StrCmpLogicalW Windows API。
有关详细信息,请参阅This Artice。
答案 3 :(得分:4)
我知道这可能会迟到,但这是另一种完美运作的解决方案
FileInfo[] files = di.GetFiles().OrderBy(n => Regex.Replace(n.Name, @"\d+", n => n.Value.PadLeft(4, '0')));
在OrderBy Clause
:
Regex.Replace(n.Name, @"\d+", n => n.Value.PadLeft(4, '0'))
这是做什么的,它pads
文件名中的数值,每个数字的长度为4个字符:
0-0.jpeg -> 0000-0000.jpeg
0-1.jpeg -> 0000-0001.jpeg
0-5.jpeg -> 0000-0005.jpeg
0-9.jpeg -> 0000-0009.jpeg
0-10.jpeg -> 0000-0010.jpeg
0-12.jpeg -> 0000-0012.jpeg
但这只发生在OrderBy
子句中,它不会以任何方式触及原始文件名。你最终将在数组中的顺序是&#34;人类自然&#34;顺序。
答案 4 :(得分:0)
您的文件名似乎是结构化的。如果你只是对它们进行排序,它们将排序为普通字符串你需要:
就个人而言,我会创建一个表示文件名中隐含的结构的类。也许它应该包裹FileInfo
。该类的构造函数应将文件名解析为其组成部分,并适当地实例化该类的属性。
该类应实现IComparable
/ IComparable<T>
(或者您可以创建Comparer的实现。)
对对象进行排序,然后它们应按照您想要的整理顺序出现。
如果您的文件名看起来像由3部分组成:
所以你的课可能看起来像
public class MyFileInfoWrapper : IComparable<MyFileInfoWrapper>,IComparable
{
public MyFileInfoWrapper( FileInfo fi )
{
// your implementation here
throw new NotImplementedException() ;
}
public int Hi { get ; private set ; }
public int Lo { get ; private set ; }
public string Extension { get ; private set ; }
public FileInfo FileInfo { get ; private set ; }
public int CompareTo( MyFileInfoWrapper other )
{
int cc ;
if ( other == null ) cc = -1 ;
else if ( this.Hi < other.Hi ) cc = -1 ;
else if ( this.Hi > other.Hi ) cc = +1 ;
else if ( this.Lo < other.Lo ) cc = -1 ;
else if ( this.Lo > other.Lo ) cc = +1 ;
else cc = string.Compare( this.Extension , other.Extension , StringComparison.InvariantCultureIgnoreCase ) ;
return cc ;
}
public int CompareTo( object obj )
{
int cc ;
if ( obj == null ) cc = -1 ;
else if ( obj is MyFileInfoWrapper ) cc = CompareTo( (MyFileInfoWrapper) obj ) ;
else throw new ArgumentException("'obj' is not a 'MyFileInfoWrapper' type.", "obj") ;
return cc ;
}
}
答案 5 :(得分:0)
针对您的具体情况实施Comparison方法,并在Array.Sort
中使用它。
private int CompareByNumericName(FileInfo firstFile, FileInfo secondFile)
{
/* First remove '0-' and '.jpeg' from both filenames then... */
int firstFileNumericName = Int32.Parse(firstFile.Name);
int secondFileNumericName = Int32.Parse(secondFile.Name);
return firstFileNumericName.CompareTo(secondFileNumericName);
}
FileInfo[] files = di.GetFiles();
Array.Sort<FileInfo>(files, CompareByNumericName);
答案 6 :(得分:0)
这是我的解决方案。我首先解析文件路径,然后定义顺序规则。
对于以下代码,您需要名称空间void Fifth_task(std::list<std::string>& lst) {
std::list<std::string>::iterator it;
std::set<char> seen;
lst.remove_if([&](const std::string& s) {
char c = std::tolower(s[0]);
bool remove = (seen.count(c) > 0);
seen.insert(c);
return remove; });
for (it = lst.begin(); it != lst.end(); ++it) {
std::cout << *it << std::endl;
}
}
。
System.Text.RegularExpressions