How to sort with LINQ with one LIST<T> inside another?

Asked

Viewed 540 times

3

Apparently easy but I’m not able to make a LINQ that orders two LIST that are nested. I don’t know if the word "nested" is correct.

How can I do this ordering through LINQ, in the code below I present the place where I wish to do LINQ.

Current Result

/*
 * Grupo um
 *    Item1
 *    Item3
 *    Item2
 * Grupo dois
 *    Item6
 *    Item4
 *    Item5               
 */

Intended Result:

/*
 * Grupo dois
 *    Item4
 *    Item5
 *    Item6
 * Grupo um
 *    Item1
 *    Item2
 *    Item3               
 */

Follow the full code:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Combo combo = CarregarCombo();

            //Tentei essas linhas abaixo mas estão com erro:
            // Desejo fazer o LINQ no lugar dessas linhas para que eu possa fazer o foreach na LIST ordenada:

            Combo cboTeste1 = new Combo(); 
            Combo cboTeste2 = new Combo();

            cboTeste1.Grupos = combo.Grupos.OrderByDescending(g => g.Key && g.Itens.OrderBy(i => i.Value));
            cboTeste2.Grupos = combo.Grupos.OrderByDescending(g => g.Key).ToList().ForEach(g => g.Itens.OrderBy(i => i.Value)));

            foreach (var grupo in combo.Grupos) //Trocar aqui para usar cboTeste1.Grupos ou cboTeste2.Grupos
            {
                Console.WriteLine(grupo.Text);

                foreach (var item in grupo.Itens)
                {
                    Console.WriteLine(" " + item.Text);
                }
            }

            Console.ReadKey();
        }

        private static Combo CarregarCombo()
        {
            Grupo grupo1 = new Grupo();
            grupo1.Text = "Grupo um";
            grupo1.Key = "1";
            grupo1.Itens = new List<Item>();

            Item item1 = new Item();
            item1.Text = "Item1";
            item1.Value = "1";
            grupo1.Itens.Add(item1);

            Item item3 = new Item();
            item3.Text = "Item3";
            item3.Value = "3";
            grupo1.Itens.Add(item3);

            Item item2 = new Item();
            item2.Text = "Item2";
            item2.Value = "2";
            grupo1.Itens.Add(item2);

            Grupo grupo2 = new Grupo();
            grupo2.Text = "Grupo dois";
            grupo1.Key = "2";
            grupo2.Itens = new List<Item>();

            Item item6 = new Item();
            item6.Text = "Item6";
            item6.Value = "6";  
            grupo2.Itens.Add(item6);

            Item item4 = new Item();
            item4.Text = "Item4";
            item4.Value = "4";
            grupo2.Itens.Add(item4);

            Item item5 = new Item();
            item5.Text = "Item5";
            item5.Value = "5";
            grupo2.Itens.Add(item5);

            Combo combo = new Combo();
            combo.Grupos = new List<Grupo>();
            combo.Grupos.Add(grupo1);
            combo.Grupos.Add(grupo2);

            return combo;
        }
    }

    public class Combo
    {
        public List<Grupo> Grupos { get; set; }
    }

    public class Grupo
    {
        public string Text { get; set; }
        public string Key { get; set; }
        public List<Item> Itens { get; set; }
    }

    public class Item
    {
        public string Text { get; set; }
        public string Value { get; set; }
        public bool Selected { get; set; }
    }
}

2 answers

3


Example:

static void Main(string[] args)
{
    Combo combo = CarregarCombo();

    //ordenando os grupos.        
    combo.Grupos = combo.Grupos.OrderBy(o => o.Key).ToList();

    //ordenando e atribuindo a mesma variavel Itens
    combo.Grupos.ForEach(c =>
    {
        c.Itens = c.Itens.OrderBy(d => d.Value).ToList();
    });  

    foreach (var grupo in combo.Grupos)
    {
        Console.WriteLine(grupo.Text);

        foreach (var item in grupo.Itens.OrderBy(c => c.Value))
        {
            Console.WriteLine(" " + item.Text);
        }
    }

    Console.ReadKey();
}

Observing: These two ordinations may need an adjustment in the field Value that instead of being a int, is as string and further research could be problematic. Another point, if you need multiple sort types of the same list is to only assign the new values in new variables.

  • I created the example in a part application allowing to use the group.Itens.Orderby(c => c.Value)), in the real application I can not do neither in the select orderby nor the way you put the top pq I will use this result in more than one place and sometimes via JSON.

  • @Mauricioferraz because?

  • Would you like everything on a single LINQ, can you? | I don’t even know if it’s possible but I think it is possible. Anyway thanks so much for the help.

  • You want @Mauricioferraz in these two lines combo.Grupos.OrderByDescending(g => g.Key).ToList(); ?

  • I want a single LINQ (one line) to order the two lists at once.

  • @Mauricioferraz did it differently see if that’s it?

  • Edited by @Mauricioferraz....

  • 1

    This code of the two Linqs that you put solved my problem, I do not know if it has how to do in one but yours perfectly solves my problem. Thank you very much. About the field being string it was int but for my case I thought I’d better use string and I won’t have problems with that. Anyway thanks for the tip.

Show 3 more comments

3

I didn’t quite understand your doubt, but it’s not enough to order the return?

 public static void Main(string[] args)
    {
        Combo combo = CarregarCombo();

        foreach (var grupo in combo.Grupos.OrderBy(g => g.Key))
        {
            Console.WriteLine(grupo.Text);

            foreach (var item in grupo.Itens.OrderBy(c => c.Value))
            {
                Console.WriteLine(" " + item.Text);
            }
        }

        Console.ReadKey();
    }

See a functional example in Ideone.

  • In one of the parts of the system I use a $.ajax request and take the return in JSON format and then and then I go through the group and item with $.each, so I wanted to bring the ordered data already. Thank you.

  • @Mauricioferraz You bring this data from the database?

  • @Yes and no, I bring some data from the database and then do a merge type (manual) on top of fixed data that is in the code to generate my data that is used to feed the combo.Grupos.Thank you for your help doubt was even knowing only if there was a way to do only with a LINQ.

Browser other questions tagged

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