Home > other >  Order IGrouping in C#
Order IGrouping in C#

Time:11-13

Example is here, should work in online compilers:

internal class Program
    {
        static void Main(string[] args)
        {
            var i1 = new Item();
            i1.Val1 = 1;
            i1.Val2 = 2.1;

            var i2 = new Item();
            i2.Val1 = 1;
            i2.Val2 = 1.5;

            var i3 = new Item();
            i3.Val1 = 3;
            i3.Val2 = 0.3;

            var list = new List<Item>
            {
                i1,
                i2,
                i3
            };
            var grouped = list.GroupBy(x => x.Val1);

            Program p = new Program();
            foreach(var group in grouped)
                p.Func(group);
            
        }

        public void Func(IGrouping<int, Item> list)
        {
            list.OrderBy(x => x.Val2); //list will be ordered, but not saved
            list = (IGrouping<int, Item>)list.OrderBy(x => x.Val2); //exception
        }
    }

    public class Item
    {
        public int Val1 { get; set; }
        public double Val2 { get; set; }
    }

It's simplified code of what I'm trying to do - I need to order list inside Func, but I have no idea how. First line works in theory, but since it's not a void it's not working in practice - list is not actually ordered.

Second line should work, actually Visual Studio suggested that, but it throws runtime exception - Unable to cast object of type System.Linq.OrderedEnumerable to System.Linq.IGrouping.

I'm out of ideas for the time being, but there is no way of bypassing it - I absolutely need to order it there.

CodePudding user response:

Try this.

 var grouped = list.GroupBy(x => x.Val1).Select(a=> a.OrderBy(a=>a.Val2).ToList());

OrderBy returns IOrderedEnumerable you can't cast that to IGrouping

CodePudding user response:

Your example code doesn't show what you are trying to arrive at.

list.OrderBy(x => x.Val2); //list will be ordered, but not saved

OrderBy returns a new list. It doesn't order the existing list in-place.

list = (IGrouping<int, Item>)list.OrderBy(x => x.Val2); //exception

OrderBy returns an IOrderedEnumerable<TElement>. Both IOrderedEnumerable<TElement> and IGrouping<TKey,TElement> derive from IEnumerable<TElement> but you can't cast an IOrderedEnumerable to an IGrouping.

If all you want is to write out the values, then Func could be:

        public IEnumerable<Item> Func(IGrouping<int, Item> list)
        {
            return list.OrderBy(x => x.Val2);
        }

and the foreach loop could be:

            foreach(var group in grouped)
            {
                var orderedList = p.Func(group);
                Console.WriteLine($"group: {group.Key}");
                foreach (var value in orderedList)
                {
                    Console.WriteLine($" {value.Val2}");
                }
            }

Hopefully this helps.

  • Related