To sort a list of objects by TWO properties

Asked

Viewed 3,070 times

7

On this topic: How to sort list with complex object by one of its properties? is explained as ordering by a property, but as ordering by two?

Taking into account the following product class:

+-------------------+--------------------+ 
| Produto                                | 
+-------------------+--------------------+ 
| Código            | int                | 
| Nome              | string             | 
| Preço             | double             | 
| Categoria         | Categoria          | 
+-------------------+--------------------+ 

And the class category

+-------------------+--------------------+ 
| Categoria                              | 
+-------------------+--------------------+ 
| Código            | int                | 
| Nome              | string             | 
+-------------------+--------------------+ 

And imagining a list of products.

How can I sort the list by alphabetical order of your category name, followed by alphabetical order of your name? You can use the IComparer?

  • 1

    You couldn’t use LINQ?

  • I don’t know this library, it already has a function that does it in it?

1 answer

8


Do with Linq, first make sure to be referencing:

using System.Linq;

Then use it like this:

var ordenada = lista.OrderBy(m => m.Categoria.Nome).ThenBy(m => m.Nome);

Use the return list ordenada to go through. Like this:

foreach (var item in ordenada)
{
    Console.WriteLine(item.Nome + " - " + item.Categoria.Nome);
}

Using query syntax this way is equivalent to the previous:

var ordenada = from m in lista
               orderby m.Categoria.Nome, m.Nome
               select m;

The OrderBy returns a list of type IOrderedEnumerable<T> so it is only possible to use the ThenBy after the OrderBy. If it were necessary to add a third property it would come with another ThenBy and so on.

If you just wanted to change the original list without having a new ordered copy, you could do so by calling the method ToList() in that way:

lista = lista.OrderBy(m => m.Categoria.Nome).ThenBy(m => m.Nome).ToList();

See that it would also be possible to call the OrderBy twice that way:

var ordenada = lista.OrderBy(m => m.Nome).OrderBy(m => m.Categoria.Nome);

It would be necessary to invert the sequence, since the entire list would be ordered twice (which should be less performatic). But besides not being very semantic, it is also not the form of use for which the OrderBy was designed.

  • Now that you edited got confused, is this "ordered var" necessary? When I need to go through the objects in the list, I go through var or the list itself?

  • 1

    Sorry, my goal was to make the answer more complete. But you do need to use the list ordenada back on the way.

  • How to use values within ordenada ? How to traverse the values within it?

  • If you can go through the elements of a list, nothing changes. The list ordenada contains the same type of elements as the lista original.

  • I can’t do it: sorted[0]. Name as I did on the original list...

  • 1

    Um, got it... do it: var ordenada = lista.OrderBy(m => m.Categoria.Nome).ThenBy(m => m.Nome).ToList(); adding the call ToList() to the returned list

  • For some reason, it returns the error "Undefined object reference to an instance of an object." where the Products list is filled in and I can use it

  • Ah, I looked deep and realized that the Category is null, sorry, my mistake!

  • 1

    I edited the answer to add other options that probably meet what you need.

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.