Others already gave you the solution. Since you seemed to be new to LINQ, I thought it might be useful to provide some background information on how LINQ works, and how to use Lambda expressions.
I see that you have two questions:
- Given a sequence of Jobs, how do I order them by a specific property?
- If I have two string to compare, how do I specify that I want Job3 before Job11
How to sort by the value of a property using LINQ
A sequence of Jobs, is every object that implements IEnumerable<Job>
, like your List<Job>
, but it could also be an array, a database query, some information to be fetched from the internet, anything that implements IEnumerable<Job>
. Usually all classes that represent a sequence of similar objects implement this interface
LINQ is nothing more than a set of methods that take an IEnumerable of something as input and returns some specified output. LINQ will never change the input, it can only extract data from it.
One of the LINQ methods is Enumerable.OrderBy. This method has a parameter keySelector
. This parameter selects the key by which you want to order. You want to order by ascending value of Customer, so your keySelector should tell the method to use property Customer.
The keySelector
has a format of Func<TSource, TKey>
. Your input sequence is a sequence of Jobs, so TSource is Job. The func is a description of a function that has as input a Job, and as output the key that you want to sort by. This would be something like:
string GetOrderByKey(Job job)
{
return job.Customer;
}
Note: the return value is a string, so everywhere that you see TKey, you should think of string.
Luckily, since the introduction of Lambda expressions this has become a lot less typing:
IEnumerable<Job> jobs = ...
var jobsOrderedByCustomer = jobs.OrderBy(job => job.Customer);
In words:
We have a sequence of Jobs, and for every job object in this sequence, return a key with a value of job.Customer. Order the Jobs by this returned key.
The first time you see lambda expressions, it might seem a bit intimidating. Usually it helps if you use plural nouns for the collections (jobs), and singular nouns for elements of the collection (job).
The phrase job => ...
would mean: for every job in the collection of jobs do ...
The part after the =>
doesn't have to be simple, it can be a block:
job =>
{
if (String.IsNullOrEmpty(status))
return job.Company;
else
return job.City;
}
So if you need to provide a Func<TSource, TKey>, you can write x => ...
where x is considered an input element of type TSource, and ... is the return value of the function, which should be of type TKey
I don't want standard ordering
If you use the overload of Enumerable.OrderBy
without a comparer, the orderby method uses a default comparer for type TKey.
So if your keySelector returns an int, the standard comparer for ints is used, if your keySelector returns a string, the standard string compare is used, which is StringComparer.Ordinal.
You don't want the standard comparison, you want a comparer that says that Job3
should come before Job11
. You need to provide a comparer. This comparer should implement IComparer<TKey>
, where TKey is the return value of your keySelector, in this case a string.
class CompanyNameComparer : IComparer<string>
{
public public int Compare (string x, string y)
{
// TODO implement
}
}
The implementation should return a number that indicates whether x should come first (< 0), or y (> 0), or that you don't care (==0).
var orderedJobs = jobs.Orderby(job => job.Company, new CompanyNameComparer());
Others already gave you a solution for the comparer, so I won't repeat it.
What might help you to get on track using LINQ, is The standard LINQ operators