sort an array of a class in C# - c#

In my program, I have a class like this:
Class Customer{
double Start;
double Finish;
double Wait;
}
and I created an array of this class:
Customer[] customer = new Customer[300];
How I can sort this array according to Start values Descending or Ascending?
Thanks...

You could use the Array.Sort method to sort the array in-place:
Array.Sort(customer, (x, y) => x.Start.CompareTo(y.Start));
or in descending order
Array.Sort(customer, (x, y) => y.Start.CompareTo(x.Start));

If would prefer to use a List of Customer, however you can apply the same function on the array:
List<Customer> customerList = new List<Customer>;
var orderedCustomerList = customerList.OrderBy(item => item.Start);
Refer to:
Enumerable.OrderBy Method
Enumerable.OrderByDescending Method

In ascending order by Start:
var sortedCustomers = customer.OrderBy(c => c.Start);
And descending order by Start:
var sortedCustomers = customer.OrderByDescending(c => c.Start);

you need to use icomparer and you need to write your custom code after implementing icomparer in your class

you need to implement IComparable for your Customer class.
http://msdn.microsoft.com/en-us/library/system.icomparable%28v=vs.80%29.aspx

C# Tutorial - Sorting Algorithms
Sorting algorithm
You can also use LINQ Dynamic Sort With LINQ
How to sort an array of object by a specific field in C#?

Related

Sort tuple list in C#

Working on C#.NET.
I have this list:
List<Tuple<string, float>> sort = new List<Tuple<string, float>>();
I want to sort this list by the float value. Eg if the list is like this:
a,45
b,2
s,32
se,83.21
te,84
s3,9.5
f,7
I want it to be sorted in a descending order, like this:
te,84
se,83.21
a,45
s,32
s3,9.5
f,7
b,2
If you want to sort the list inplace, you can use the Sort method that takes Comparison<T> argument.
To sort by the Tuple.Item2 in ascending order, you can use
sort.Sort((a, b) => a.Item2.CompareTo(b.Item2));
To sort in descending order, just swap a and b:
sort.Sort((a, b) => b.Item2.CompareTo(a.Item2));
You wouldn't sort the list - you'd create a new list which contains the same items, but is sorted.
var sorted = sort.OrderByDescending(t => t.Item2).ToList();
Here is an easy way to sort the list:
sort = sort.OrderByDescending(s => s.Item2).ToList();
If you don't want to create a new list you can use the IComparer<> interface to create a customer comparer.
public class MyCompare : IComparer<Tuple<string, float>>
{
public int Compare(Tuple<string, float> x, Tuple<string, float> y)
{
return y.Item2.CompareTo(x.Item2);
}
}
... then you would use it like this ...
sort.Sort(new MyCompare());

Sort List in C#

So I have this C# list:
List<DatsWussup.Models.JQGridMessage> gridMessages = new List<DatsWussup.Models.JQGridMessage>();
Each JQGridMessage has a property called age. What's the quickest and most efficient way to sort this list by age (youngest first). Age is an int.
Thanks!
The List<T> class has a Sort method which can be used to in place sort the data. One overload takes a Comparison delegate that can be implemented via an anonymous function. For example
gridMessages.Sort((x, y) => x.Age.CompareTo(y.Age));
Use Linq:
var sortedEnumerable = gridMessages.OrderBy(m => m.Age);
This will return a new IEnumerable sorted by age.
gridMessages.Sort((m1, m2) => m1.Age.CompareTo(m2.Age));
Can you use:
gridMessages = gridMessages.OrderBy(x => x.age).toList();

Select from a List<T>

I'm sure there's an wasy way of doing this (I'm guessing one of the extension methods?), but am struggling to find it with Google.
Basically I have a List of custom classes; I want to select some items from this into a new List where one of the properties is equal to any value in another List.
Here's a (simplified) quick example of what I'm trying to do:
public class Job
{
public int Number;
public string ClientCompanyName;
}
List<Job> lstJobs = new List<Job>();
List<Job> lstCompare = new List<Job>();
normally I would do something like:
List<Job> lstFiltered = new List<Job>();
foreach(Job jobThis in lstCompare)
{
foreach(jobComp in lstCompare)
{
if(jobThis.Number = jobComp.Number)
{
lstFiltered.Add(jobThis);
}
}
}
Is there an extension method that neatens this last bit up into (ideally) a single line?
Cheers
You can use Intersect() for this:
http://msdn.microsoft.com/en-us/library/bb460136.aspx
Use Intersect.
For it to work with your custom comparison you either need to implement IEquatable<T> in your class or create a new class the implements IEqualityComparer<T> for your class and pass that to the overload of Intersect.
Jez,
You might be able to use the LINQ intersect function, or try:
var matches = from jobs in lstJobs
join comp in lstCompare on jobs.Number equals comp.Number
select jobs;
or LINQ syntax:
var matches = lstJobs.Join(lstCompare, jobs => jobs.Number,
comp => comp.Number, (jobs, comp) => jobs);
and here was reSharper's version based on your original loop:
List<Job> lstFiltered = (lstJobs.SelectMany(jobThis => lstCompare,
(jobThis, jobComp) => new {jobThis, jobComp})
.Where(#t => #t.jobThis.Number == #t.jobComp.Number)
.Select(#t => #t.jobThis)).ToList();
slightly verbose, but another way to skin the cat.
[edited] as had set to new list, rather than selected elements - doh
var lstFiltered = lstJobs
.Where(job => lstCompare.Any(item => item.Number == job.Number))
.ToList();
The above solution works well if the number of items in the lstCompare is small. For bigger comparison lists you may want to use some hash based collection.
var compareSet = new HashSet<int>(lstCompare.Select(item => item.Number));
var lstFiltered = lstJobs
.Where(job => compareSet.Contains(job.Number))
.ToList();
If the comparison condition is more complex or it is needed in several places, you should create a comparer class that implements IEqualityComparer<T>. Then you could use the Intersect() method as others have already suggested. However, it is not functionally identical with the above solutions. It returns only distinct elements while my solutions return all matching elements. It may be a significant difference in some applications.
My second example can be easily changed to use IEqualityComparer<T> if necessary. The HashSet<T> takes the comparer as second parameter.

How to sort a list with two sorting rules?

I have a list that I want to sort using to parameters. That means it are all values and if for example I have
A 2/2
B 3/3
C 3/4
I want the sorting C B A
I tried to implement that the following way:
methods.Sort((y, x) => x.GetChangingMethodsCount().CompareTo(y.GetChangingMethodsCount()));
methods.Sort((y, x) => x.GetChangingClassesCount().CompareTo(y.GetChangingClassesCount()));
First sort the list with the second parameter and then sort it again with the first parameter. But the ordering isn0t correct. Any hints how to achieve that?
What you need to do is combine the two sort keys into a single function. If the first comparison returns 0, only then try the second one:
methods.Sort((y, x) =>
{
int sort = x.GetChangingClassesCount().CompareTo(y.GetChangingClassesCount());
if (sort == 0)
sort = x.GetChangingMethodsCount().CompareTo(y.GetChangingMethodsCount());
return sort;
});
Probably the easiest way is to use the OrderBy and ThenBy extension methods like that :
methods.OrderByDescending(x => x.GetChangingMethodCount()).
ThenByDescending(x => x.GetChangingClassesCount()).
ToList();
It's not clear (to me at least) if this is what you want based on your example, but you could give this a try:
var sortedMethods = methods.OrderByDescending(m => m.GetChangingMethodsCount()).ThenByDescending(m => m.GetChangingClassesCount());

Sorting a list in C# (with various parameters)

I have a list of objects. That objects have various field, e.g. age and name
Now sometimes I'd like to sort the list by names and sometimes by age. Additional sometimes increasing order and sometimes decreasing order.
Now I understand that i should implement the Comparable interface in my object and override the CompareTo method.
But how can i do this when i want to support various sorting orders?
Do i have to set the sorting order in my object or is it somehow possible to pass the sorting order by the sort method call?
The method call can do everything; no need for a comparer:
list.Sort((x,y)=>string.Compare(x.Name,y.Name));
list.Sort((x,y)=>y.Age.CompareTo(x.Age)); // desc
list.Sort((x,y)=>x.Age.CompareTo(y.Age)); // asc
Note the second is descending, by swapping x/y in the compare.
If you're using List<T> and you want to sort the list in place, then the Sort function provides an overload that accepts a Comparison<T>. You can use this to provide different comparisons for a list.
For example, to sort on Age:
list.Sort((x, y) => x.Age.CompareTo(y.Age));
To sort on Name:
list.Sort((x, y) => string.Compare(x.Name, y.Name));
To sort in descending order, simply reverse the parameters.
Alternatively, you could use LINQ to create various queries against your list that provide the results in whatever order you like, but this won't have any effect upon the underlying list (whether that's bad or good is up to you):
var byAge = list.OrderBy(x => x.Age);
var byName = list.OrderBy(x => x.Name);
To sort in descending order, use OrderByDescending in place of OrderBy.
You can also just use LINQ to handle this:
var sortedByAge = myList.OrderBy(i => i.Age);
var sortedByName = myList.OrderBy(i => i.Name);
If you want to handle sorting in place, you can use List<T>.Sort(Comparison<T>):
// Sort by Age
myList.Sort( (l, r) => l.Age.CompareTo(r.Age) );
// Sort by Name
myList.Sort( (l, r) => l.Name.CompareTo(r.Name) );
You can sort your objects data with linq
something like this
var query = from cust in customers
orderby cust.Age ascending
select cust;
You can also use
list.OrderByDescending(a => a.Age);
or
list.OrderByAscending(a => a.Age);

Categories

Resources