我正在编写一个程序,计算一个文件夹中有多少行代码,您在其中输入要检查的扩展名(例如.cs
),它列出了所有带有该扩展名的文件及其代码行像这样:
1. BackgroundProcesses.cs: 153
2. App.xaml.cs: 15
3. MainTableManifest.cs: 41
目前,我只是使用Directory.GetFiles()
来获取文件,并且它们没有任何特定的顺序。但是,我想按照每个文件从最小到最大显示多少行来对每个文件进行排序,以便通过这样的输出轻松查看最大的文件:
1. App.xaml.cs: 15
2. MainTableManifest.cs: 41
3. BackgroundProcesses.cs: 153
这是我的二维锯齿状数组的基本外观:
string[][] arr = new string[][] {
new string[]{"file1", "324"},
new string[]{"file2", "1903"},
new string[]{"file3", "617"}
};
显然,排序时我需要将字符串转换为数字(我不认为您可以将锯齿形数组的数组类型设置为不同的值)。关于如何将锯齿状数组转换为类似内容的任何想法?
string[][] arr = new string[][] {
new string[]{"file1", "324"},
new string[]{"file2", "617"},
new string[]{"file3", "1903"}
};
您应该使用ValueTuple而不是锯齿数组。
(string Filename, int Lines)[] files = ...
此后,您可以使用Linq进行排序
var sorted = files
.OrderBy(item => item.Lines)
.ThenBy(item => item.Filename);
诸如C#之类的面向对象编程语言的主要要点之一是允许您定义自定义对象并具有与之相关的行为,而不是本机类型的复杂结构。
您是否尝试过创建自定义对象来表示可以随后进行相应排序的数据?例如
public class FileRecord
{
public string FileName { get; }
public int NumberOfLines { get; }
public FileRecord(string fileName, int numberOfLines)
{
this.FileName = fileName;
this.NumberOfLines = numberOfLines;
}
}
然后,您可以使此类实现IComparable或为排序定义一个自定义比较器。我的偏好是使用自定义比较器,因为您可能希望使用其他条件和其他地方的相同类进行排序。
这看起来像:
public class FileRecordComparer : IComparer<FileRecord>
{
public int Compare(FileRecord x, FileRecord y)
{
// Could handle nulls here if you're expecting nulls
return x.NumberOfLines.CompareTo(y.NumberOfLines);
}
}
然后,您可以使用以下代码对数组进行排序(当然,必须以当前的方式填充它)
// Could use a list here if you don't know the number of files
FileRecord[] records = new FileRecord[numberOfFiles];
// ...
// Populate the records as you do currently, but creating instances of FileRecord
// ...
Array.Sort(records, new FileRecordComparer());