Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort list type generic if more than one property?

I have a list-generic that has a property (class type). I need a sort method for Z parameters (TrainingSet):

public override List<TrainingSet> CalculatedDistancesArray
    (List<TrainigSet> ts, double x, double y, int k)
{
    for (int i =0; i < ts.Count; i++)
    {
        ts[i].Z = (Math.Sqrt(Math.Pow((ts[i].X - x), 2) 
                  + Math.Pow((ts[i].Y - y), 2)));
    }
    // I want to sort according to Z
    ts.Sort(); //Failed to compare two elements in the array.
    List<TrainingSet> sortedlist = new List<TrainingSet>();
    for (int i = 0; i < k; i++)
    {
        sortedlist.Add(ts[i]);
    }
    return ts;
}

public class TrainigSet
{
    public double X { get; set; }
    public double Y { get; set; }
    public double Z { get; set; }
    public string Risk { get; set; }
}
like image 948
ALEXALEXIYEV Avatar asked May 09 '09 09:05

ALEXALEXIYEV


3 Answers

Just sorting on a single property is easy. Use the overload which takes a Comparison<T>:

// C# 2
ts.Sort(delegate (TrainingSet o1, TrainingSet o2) 
       { return o1.Z.CompareTo(o2.Z)); }
);

// C# 3
ts.Sort((o1, o2) => o1.Z.CompareTo(o2.Z));

Sorting on multiple properties is a bit trickier. I've got classes to build up comparisons in a compound manner, as well as building "projection comparisons" but if you really only want to sort by Z then the above code is going to be as easy as it gets.

If you're using .NET 3.5 and you don't really need the list to be sorted in-place, you can use OrderBy and ThenBy, e.g.

return ts.OrderBy(t => t.Z);

or for a more complicated comparison:

return ts.OrderBy(t => t.Z).ThenBy(t => t.X);

These would be represented by orderby clauses in a query expression:

return from t in ts
       orderby t.Z
       select t;

and

return from t in ts
       orderby t.Z, t.X
       select t;

(You can also sort in a descending manner if you want.)

like image 189
Jon Skeet Avatar answered Nov 03 '22 07:11

Jon Skeet


var sortedList = 
      list.OrderBy(i => i.X).ThenBy(i => i.Y).ThenBy(i => i.Z).ToList();
like image 43
mmx Avatar answered Nov 03 '22 07:11

mmx


You could try this. It worked for me:

ts.Sort(delegate(TrainingSet a, TrainingSet b) { return a.X.CompareTo(b.X) != 0 ? a.X.CompareTo(b.X) : a.Y.CompareTo(b.Y); });
like image 20
MyFriend Avatar answered Nov 03 '22 07:11

MyFriend