我正在读取分号分隔的文件中的行,我在这里找到了如何排序列表:
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);我不得不在分类键中使用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时修剪字段,我只想在排序时修剪所有字段,这可能吗?
发布于 2014-11-13 11:15:32
首先,将数据存储在一个更专业的对象中:
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));
}
}请注意,我不会推荐这个。(而且,我不能百分之百确定它是否有效,我还没有测试过它,但是你可以看到这些概念是什么。)
如果您首先将行转换为一个更有意义的对象,例如使用FileHelpers,您的情况会更好。对“拆分字符串的第四部分”进行排序本质上是没有意义的,而且是IMHO错误代码,因为它要求您确定输入文件的格式;将一行转换为有意义的对象(例如,第一部分是ID,第三部分是名称等)允许您编写更有意义的代码。
顺便说一句,微软的不喜欢匈牙利符号 WRT到C#:sList和sSortedList开头的"s“,还有,我建议不要在不是这样的的时候把东西命名为"sortedList”。
发布于 2014-11-17 08:49:15
@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));
}其实,我还不习惯写作课,希望这第一次真正的尝试是可以的。我需要更多的评论,看看是否有更好的方法来做到这一点。
顺便说一句,FileHelpers只适用于.NET 1.1和2.0,没有.NET 4.5的支持,对于这个优秀的支持来说,这是多么微不足道的一件事。
https://stackoverflow.com/questions/26906049
复制相似问题