Question

I have a class with two properties, Name and Position. I would like to order the list with this class by Position, and the elements with the same position should be ordered by Name. I am working on a static list, so I would like to work in-place.

So far I managed to order the list by one property:

list.Sort((x, y) => x.Position.CompareTo(y.Position));

this code is working and I have the list ordered by Position, but I don't know how to implement the second part. I found this question, but I don't understand the answer.

Could anyone please help me?

Was it helpful?

Solution 2

The answer you linked to is correct. The key in sorting by multiple values is that the secondary property only matters if the primaries are equal. A psuedocode implementation of your sort comparison might be:

compare x and y position
if they differ, return order
else compare name, return order

On the Sort method, the code following the (x,y)=> must return 0 if the items are equal, a negative number if the first should be before the second, and a positive number if the second should come before the first. The CompareTo method will return -1, 0, or 1 based on these cases and its arguments. Since you need to compare two different properties, you need two calls to CompareTo. If you decided to add them together, you could have a case like this:

  • x.position < y.position (compare returns -1)
  • x.name > y.name (compare returns 1)
  • result 0, items are considered equal, where your rules clearly say x should come first in this case.

To solve this issue, we need to make sure the Name comparison only matters when the positions are equal. Since CompareTo only returns -1, 0, or 1, if we multiply the position result by 2 (or any larger number) then the Name comparison will only change the result if the positions are equal. (Because -2 + 1 = -1 and 2 - 1 = 1)

So using the method in your original linked answer, your code would be something like:

list.Sort((x, y) => 
    2 * x.Position.CompareTo(y.Position) 
    + x.Name.CompareTo(y.Name));

OTHER TIPS

I would use "OrderBy" and "ThenBy":

  IEnumerable<Person> orderedPersons = persons.OrderBy(item => item.Position)
            .ThenBy(item => item.Name);
list = list.OrderBy(item => item.Name).ToList();
list.Sort((x, y) => x.Position.CompareTo(y.Position));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top