在Foreach循环C#中使用Orderby的差异

时间:2018-07-05 12:50:34

标签: c#

伙计们,我一直在尝试按其名称末尾的子字符串对文件进行排序,而该字符串恰好以一个数字结尾,该数字指示其相对于其余文件的位置。 (例如:fs-1632_1.txt-> fs-1632_2.txt)。

我目前能够获取数字并将其转换为整数,但是我在使OrderBy方法正确运行方面遇到问题。我主要从事this example of Orderby的工作。

在此方面的任何帮助将不胜感激。

internal class Data
{
    public string Name { get; set; }
    public double Number { get; set; }
}

private void OrderByEx1(List<FileInfo> files)
{
    int num = 0;
    int index_num = 0;
    string file_num  = "";
    string file_name = "";

    foreach (FileInfo in files)
    { 
        file_name = file.FullName;
        file_name = Path.GetFileNameWithoutExtension(file_name);

        index_num = file_name.LastIndexOf("_") + 1;
        file_num  = file_name.Substring(index_num);

        num = Int32.Parse(file_num);

        Data[] set = {new Data {Name = file_name, Number = num }};

    }
    IEnumerable<Data> query = set.OrderBy(data => data.Number);

    foreach (Data file_s in query)
        MessageBox.Show($"{file_s.Name} {file_s.Number}");
}

2 个答案:

答案 0 :(得分:2)

您要声明一个名为set的Data数组,向其中添加一个元素,然后重新启动循环,而忘记在上一个循环中已加载的内容。该命令仅在退出循环时执行,但此时set数组包含一个元素,即最后一个元素。

您需要将数据结构添加到列表中,然后订购该列表

    List<Data> dataFiles = new List<Data>();
    foreach (FileInfo file in files)
    { 
        file_name = file.FullName;
        file_name = Path.GetFileNameWithoutExtension(file_name);

        index_num = file_name.LastIndexOf("_") + 1;
        file_num = file_name.Substring(index_num);

        num = Int32.Parse(file_num);

        dataFiles.Add(new Data {Name = file_name, Number = num });
    }
    // If you don't need the query var you can just order directly in the for loop
    // IEnumerable<Data> query = dataFiles.OrderBy(data => data.Number);

    foreach (Data file_s in dataFiles.OrderBy(data => data.Number))
    {
        MessageBox.Show(file_s.Name + " " + file_s.Number);
    }

答案 1 :(得分:2)

不需要foreach循环。您可以使用这种安全的LINQ方法:

files = files
    .Select(f => new { File = f, Name = Path.GetFileNameWithoutExtension(f.Name) })
    .Select(x => new
    {
        x.File,
        x.Name,
        Token = x.Name.Substring(x.Name.LastIndexOf("_", StringComparison.Ordinal) + 1)
    })
    .Select(x => new
    {
        x.File,
        x.Name,
        x.Token,
        IsInt = int.TryParse(x.Token, out int number),
        ParsedNumber = number
    })
    .OrderByDescending(x => x.IsInt)
    .ThenBy(x => x.ParsedNumber)
    .Select(x => x.File)
    .ToList();

如果没有数字或无法将其解析为int,则文件将列在底部。