2014-02-28 86 views
2

我有一个名为jobList的自定义对象列表。该列表有很多字段,但我想按两个字段进行排序,即FolderID和JobName。名单如下:订购清单<T>

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排序依据,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" 

任何人都可以帮我正确地订购清单吗?

感谢,

Chewdoggie

+1

我们可以假设'FolderID'是'int'和'JobName'是'string'? –

+0

您可以分享实际的代码,而不是只是在代码块中写出某种东西的列表? –

+0

你给OrderBy()。ThenBy'调用了什么结果吗?这些方法没有适当的排序。他们使用排序的项目创建新的集合。 – MarcinJuraszek

回答

0

enter image description here

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

似乎是工作的罚款。

+0

你是不是打算在第二个操作符上使用'ThenBy'? 'OrderBy'忽略任何以前的顺序。 –

+0

不,这正是我在LINQPAD中使用的语法,我猜想第二个orderby应用于第一个结果。 –

+0

是的。但[[ThenBy'按升序执行序列中元素的后续排序](http://msdn.microsoft.com/library/system.linq.enumerable.thenby.aspx“Enumerable.ThenBy Method”)while [ 'OrderBy'按照升序排列序列的元素](http://msdn.microsoft.com/library/system.linq.enumerable.orderby.aspx“Enumerable.OrderBy Method”)。 (...) –

1

我只能看到一种可能的消除:您不会将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()); 
+0

如果他不分配它,那么他应该得到与原始列表相同的结果。但结果不同,所以这不是问题 –

+0

@ Selman22我看不到不同的解释。即使'FolderId'是一个字符串,它会正确地排序''2“'和'”3“'项目... – MarcinJuraszek

+0

是的,但是在第一次排序之后,它按JobName排序,然后''3,oper01_quick”'在''2,max02_experion“' –

0

如果您Job类是什么样子这个:

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

    public string JobName { get; set; } 
} 

然后实现IComparer<T>

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(); 

这应该给你的预期result.Here是LINQPad输出:

enter image description here

2

你在正确的你如何做排序,但你需要将它分配给一个变量,以得到最终的排序集合:

请参阅。NET小提琴: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); 
}