【问题标题】:Ordering list<T>订货单<T>
【发布时间】:2014-03-01 04:08:13
【问题描述】:

我有一个名为 jobList 的自定义对象列表。该列表有很多字段,但我想按两个字段排序,FolderID 和 JobName。该列表如下所示:

job.FolderID = 3
job.JobName = "oper01_quick"

job.FolderID = 3
Job.JobName = "oper02_quick"

job.FolderID = 1
job.JobName = "min01_selfie"

job.FolderID = 2
job.JobName = "max01_experion"

job.FolderID = 2
job.JobName = "max02_experion"

我想对该列表进行排序,使其如下所示:

job.FolderID = 1
job.JobName = "min01_selfie"

job.FolderID = 2
job.JobName = "max01_experion"

job.FolderID = 2
job.JobName = "max02_experion"

job.FolderID = 3
job.JobName = "oper01_quick"

job.FolderID = 3
Job.JobName = "oper02_quick"

而且我认为如果我执行此 LINQ OrderBy,则 ThenBy:

jobList.OrderBy(j => j.FolderID).ThenBy(j => j.JobName);

它会做到这一点。但事实并非如此。它使订单看起来像这样:

job.FolderID = 1
job.JobName = "min01_selfie"

job.FolderID = 2
job.JobName = "max01_experion"

job.FolderID = 3
job.JobName = "oper01_quick"

job.FolderID = 2
job.JobName = "max02_experion"

job.FolderID = 3
Job.JobName = "oper02_quick"

谁能帮我正确排序列表?

谢谢,

咀嚼狗

【问题讨论】:

  • 我们可以假设FolderIDintJobNamestring
  • 你能分享实际的代码,而不是在代码块中写出一些东西的列表吗?
  • 您是否将OrderBy().ThenBy 调用的结果分配给了某些东西?这些方法没有就地排序。他们创建带有排序项目的新集合。
  • 我创建了一个 Job 类来反映你的类,然后对 OrderByThenBy 使用相同的调用,并且它正确排序。 Marcin 指出列表没有就地排序是正确的 - 您需要将方法的结果分配给某些东西。

标签: linq generics


【解决方案1】:

您的排序方式是正确的,但您需要将其分配给一个变量才能获得结果排序集合:

查看 .NET Fiddle:http://dotnetfiddle.net/wISQVv

这基本上就是它的作用:

var sortedJobs = jobs.OrderBy(j => j.FolderID).ThenBy(j => j.JobName);

foreach(var job in sortedJobs){
    Console.WriteLine(job.FolderID + " " + job.JobName);
}

【讨论】:

    【解决方案2】:

    我只能看到一种可能的解释:您没有将 OrderBy/ThenBy 结果分配回源变量。

    这些方法(以及整个 LINQ)不会更改源集合。取而代之的是,他们创建了对元素进行排序的新集合。这就是为什么您必须将其分配回去:

    jobList = jobList.OrderBy(j => j.FolderID).ThenBy(j => j.JobName).ToList();
    

    要对列表进行排序,您必须使用Sort 方法,并带有自定义比较器:

    public class JobComparer : IComparer<Job>
    {
        public int Compare(Job x, Job y)
        {
            var folderDifference = x.FolderId.CompareTo(y.FolderId);
            return folderDifference == 0 ? x.JobName.CompareTo(y.JobName) : folderDifference;
        }
    }
    
    jobList.Sort(new JobComparer());
    

    【讨论】:

    • 如果他没有分配它,那么他应该得到与原始列表相同的结果。但是结果不同,所以这不是问题
    • @Selman22 我看不出不同的解释。即使FolderId 是一个字符串,它也会正确排序"2""3" 项目...
    • 是的,但是第一次排序后,是按JobName排序,"3,oper01_quick""2,max02_experion"之前
    • @Selman22 但是ThenBy 仅适用于与之前的排序定义相同的项目的子组,因此将仅检查JobName 是否具有相同的FolderId 值。跨度>
    • 嗯,我不知道。看来您是对的,我尝试了该查询并给出了正确的结果。但仍然不明白 OP 如何获得不同的结果。
    【解决方案3】:

    jobs.OrderBy(j => j.JobName).OrderBy(j => j.FolderId)
    

    似乎工作正常。

    【讨论】:

    【解决方案4】:

    如果您的 Job 类如下所示:

    public class Job
    {
        public int FolderId { get; set; }
    
        public string JobName { get; set; }
    }
    

    然后实现IComparer&lt;T&gt;:

    public class JobComparer : IComparer<Job>
    {
        public int Compare(Job x, Job y)
        {
            if (x.FolderId != y.FolderId) return x.FolderId.CompareTo(y.FolderId);
    
            return x.JobName.CompareTo(y.JobName);
        }
    }
    

    并使用它:

    var orderedList = items.OrderBy(x => x, new JobComparer()).ToList();
    

    这应该会给出您预期的结果。这是LINQPad 中的输出:

    【讨论】:

      猜你喜欢
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      相关资源
      最近更新 更多