Matthew Chewdoggie
Matthew Chewdoggie

Reputation: 51

Ordering list<T>

I have a list of custom objects List called jobList. The list has many fields, but I want to sort by two fields, FolderID and JobName. The list looks like this:

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"

I want to sort this list so that it appears like this:

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"

And I thought that if I did this LINQ OrderBy, ThenBy:

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

that it would accomplish this. But it doesn't. It make the order look like this:

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"

Can anyone help me with ordering the list properly ?

Thanks,

Chewdoggie

Upvotes: 2

Views: 81

Answers (4)

Selman Genç
Selman Genç

Reputation: 101681

If your Job class looks like this:

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

    public string JobName { get; set; }
}

Then implement 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);
    }
}

And use it:

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

This should give your expected result.Here is the output in LINQPad:

enter image description here

Upvotes: 0

Matt Tester
Matt Tester

Reputation: 4814

You're correct in how you're doing the sorting, but you need to assign it to a variable in order to get the resulting sorted collection:

See the .NET Fiddle: http://dotnetfiddle.net/wISQVv

This is essentially what it does:

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

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

Upvotes: 2

AD.Net
AD.Net

Reputation: 13399

enter image description here

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

Seems to be working fine.

Upvotes: 0

MarcinJuraszek
MarcinJuraszek

Reputation: 125620

I can see only one possible explenation: you're not assigning OrderBy/ThenBy result back to your source variable.

These methods (and the entire LINQ) does not change source collection. Instead of that, they create new collection with elements sorted. That's why you have to assign it back:

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

To sort list in place you have to use Sort method, with custom comparer:

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

Upvotes: 1

Related Questions