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; }
}

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.)

Method 2

var sortedList = 
      list.OrderBy(i => i.X).ThenBy(i => i.Y).ThenBy(i => i.Z).ToList();

Method 3

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

Method 4

Using framework 3.5 this would simply be:

public override List<TrainingSet> CalculatedDistancesArray(List<TrainigSet> ts, double x, double y, int k) {
   foreach (TrainigSet t in ts) {
      t.Z = Math.Sqrt(Math.Pow(t.X - x, 2) + Math.Pow(t.Y - y, 2));
   }
   return ts.OrderBy(t => t.Z).Take(k).ToList();
}

Note: This will not change the order of the ts list, but create a new, sorted list to return.

(I assume that you actually wanted to return the first k items from the list, not the ts list as you do in the code in your question.)

Using framework 2 needs a little more code:

public override List<TrainingSet> CalculatedDistancesArray(List<TrainigSet> ts, double x, double y, int k) {
   foreach (TrainigSet t in ts) {
      t.Z = Math.Sqrt(Math.Pow(t.X - x, 2) + Math.Pow(t.Y - y, 2));
   }
   ts.Sort(delegate (TrainigSet t1, TrainigSet t2) { return t1.Z.CompareTo(t2.Z)); });
   List<TrainigSet> result = new List<TrainigSet>(k);
   for (int i = 0; i < k ; i++) {
      result.Add(ts[i]);
   }
   return result;
}

If you are using the Z value only for the sorting, you could skip the Math.Sqrt call and just leave the value to be the square of the distance, as that sorts exactly the same as the distance.

Method 5

You will be able to use the Sort method on the list if you implement IComparable<TrainingSet> on your type “TrainingSet”. You will have to implement a “CompareTo” method. You can then simply delegate your implementation to the “CompareTo” of your double-typed Z. This will avoid your exception.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x