首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >边排序边修剪列表

边排序边修剪列表
EN

Stack Overflow用户
提问于 2014-11-13 10:01:04
回答 2查看 660关注 0票数 0

我正在读取分号分隔的文件中的行,我在这里找到了如何排序列表:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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时修剪字段,我只想在排序时修剪所有字段,这可能吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-13 11:15:32

首先,将数据存储在一个更专业的对象中:

代码语言:javascript
复制
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]; }
    }
}

然后你可以像这样使用它:

代码语言:javascript
复制
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”。

票数 0
EN

Stack Overflow用户

发布于 2014-11-17 08:49:15

@BCdotNET我按照过去的注释编辑了您的类,并按照您的建议创建了我自己的类,以尽可能封装整个过程,我仍然在考虑如何封装csv字段名,以便使其更通用,我仍然需要更多的想法:

代码语言:javascript
复制
    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); }
        }
    }

这是我的班级:

代码语言:javascript
复制
    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;
        }
    }

我就是这样用的:

代码语言:javascript
复制
        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的支持,对于这个优秀的支持来说,这是多么微不足道的一件事。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26906049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档