我正在读取分号分隔文件中的行,我在这里找到了如何对List进行排序:
IEnumerable<string> sSortedList = sList.Select(line => new
{
SortKey1 = line.Split(';')[4].Trim(),
SortKey2 = line.Split(';')[1].Trim(),
Line = line
})
.OrderBy(Section => Section.SortKey1)
.ThenBy(StdName => StdName.SortKey2)
.Select(sResult => sResult.Line);
我必须在sortkeys中使用trim,因为如果我不这样做,我将无法正确排序..
无论如何,当我需要将列表复制到另一个列表或将它们写入DataGridView时,我必须再次使用trim:
foreach (string sLine in sSortedList)
{
if (sLine.Contains("3"))
{
dataGridView1.InvokeEx(control => control.Rows.Add(sLine.Split(';').Select(sCol => sCol.Trim()).ToArray<string>()));
listBox1.InvokeEx(control => control.Items.Add("Processed Line: " + sLine));
}
}
我不想在填充DataGridView时修剪字段,我只想在排序时修剪所有字段,这可能吗?
答案 0 :(得分:0)
首先将数据存储在更专业的对象中:
internal class ProcessedLine
{
public string Original {get; private set;}
public string[] Trimmed {get; private set;}
public ProcessedLine(string original)
{
Original = original;
Trimmed = original.Split(';').Select(x => x.Trim()).ToArray();
}
public string SortKey1
{
get{ return Trimmed[4]; }
}
public string SortKey2
{
get{ return Trimmed[1]; }
}
}
然后你可以像这样使用它:
var processedLines = sList.Select(x => new ProcessedLine(x)).ToList();
foreach (var processedLine in processedLines.OrderBy(x => x.SortKey1).ThenBy(x => x.SortKey2))
{
if (lineObject.Original.Contains("3"))
{
dataGridView1.InvokeEx(control => control.Rows.Add(lineObject.Trimmed));
listBox1.InvokeEx(control => control.Items.Add("Processed Line: " + lineObject.Original));
}
}
请注意,我不建议这样做。 (另外,我不是100%确定它有效,没有测试它,但你可以看到概念是什么。)
恕我直言,如果你将你的行首先转换为更有意义的对象,你会更好,例如使用FileHelpers。对“拆分字符串的第四部分”进行排序基本上没有意义,是恕我直言的错误代码,因为它要求你弄清楚输入文件的格式;将一行转换为具有意义的对象(例如,第一部分是ID,第三部分是名称等),允许您编写更有意义的代码。
BTW Microsoft doesn't like Hungarian notation WRT to C#:sList和sSortedList等开头的“s”。另外,我建议不要在it isn't one时命名为“sortedList”。
答案 1 :(得分:0)
@BCdotNET我设法根据过去的评论编辑你的类并创建我自己的类,因为你建议尽可能地封装整个过程,我仍然在考虑如何封装csv字段名称以便制作更一般,我还需要更多的想法:
internal class ProcessedLine
{
public string Original { get; private set; }
public string[] Trimmed { get; private set; }
public ProcessedLine(string original)
{
Original = original;
Trimmed = Original.Split(';').Select(x => x.Trim()).ToArray();
}
public string SortKey1
{
get { return Trimmed[4]; }
}
public string SortKey2
{
get { return Trimmed[1]; }
}
public string JoinedTrimmed
{
get { return string.Join(";", Trimmed); }
}
}
这是我的班级:
internal class ReadAllLinesFromFilesInDirectory
{
private List<string> AllPlainLinesFromAllFiles = new List<string>();
private List<string> SortedJoinedTrimmedAllLines = new List<string>();
public ReadAllLinesFromFilesInDirectory(string directoryPath, string TopicName, string LinesToExclude)
{
string[] fileEntries = Directory.GetFiles(directoryPath, TopicName + "*", SearchOption.TopDirectoryOnly).Where(s => s.EndsWith(".csv", StringComparison.InvariantCultureIgnoreCase)).ToArray();
foreach (string fileEntry in fileEntries)
{
List<string> ReadLinesFromFileToList = new List<string>(File.ReadAllLines(fileEntry, Encoding.Default)
.Where(x => !x.Contains(LinesToExclude))
.ToList());
for (int lineCount = 0; lineCount < ReadLinesFromFileToList.Count(); lineCount++)
{
ReadLinesFromFileToList[lineCount] = String.Format("{0};{1}", ReadLinesFromFileToList[lineCount], Path.GetFileNameWithoutExtension(fileEntry).Replace("-", string.Empty).ToUpper());
}
AllPlainLinesFromAllFiles.AddRange(ReadLinesFromFileToList);
}
}
public List<string> SortedJoinedTrimmedAllLinesToList()
{
SortedJoinedTrimmedAllLines = AllPlainLinesFromAllFiles
.Select(x => new ProcessedLine(x))
.OrderBy(x => x.SortKey1)
.ThenBy(x => x.SortKey2)
.Select(x => x.JoinedTrimmed)
.ToList();
return SortedJoinedTrimmedAllLines;
}
public List<string> ToList()
{
return AllPlainLinesFromAllFiles;
}
}
我这样使用它:
this.InvokeEx(x => x.dataGridView1.ColumnCount = columnHeader.Split(';').Count<string>());
List<string> AllLinesFromAllFilesToListTrimmedSorted = new ReadAllLinesFromFilesInDirectory("StudentList", "IT102-Cplus-Section", "StudentID").SortedJoinedTrimmedAllLinesToList();
this.InvokeEx(x => x.toolStripProgressBar1.Value = 0);
this.InvokeEx(x => x.toolStripProgressBar1.Maximum = AllLinesFromAllFilesToListTrimmedSorted.Count());
foreach (string singleLine in AllLinesFromAllFilesToListTrimmedSorted)
{
this.InvokeEx(x => x.toolStripProgressBar1.Value++);
this.InvokeEx(x => x.toolStripStatusLabel1.Text = x.toolStripProgressBar1.Value.ToString());
this.InvokeEx(x => x.dataGridView1.Rows.Add(singleLine.Split(';')));
this.InvokeEx(x => x.listBox1.Items.Add("Processed Line: " + singleLine));
}
实际上,我不习惯写课,希望这第一次真正的尝试是可以的。我需要更多评论,看看是否有更好的方法。
BTW,FileHelpers仅适用于.NET 1.1和2.0,没有.NET 4.5支持,这对于这个优秀的人来说真是太可怜了。