Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

c# groupby orderby thenby Try specifying the type arguments explicitly

I want to group using Grade and sort in descending order based on the number of elements in each group, then use the Number property to sort each group element in ascending order. I tried but it doesn’t work. Can you help me on what I’m doing wrong?

Here is the error content:
The type arguments for method ‘System.Linq.Enumerable.OrderBy<TSource,TKey>(System.Collections.Generic.IEnumerable, System.Func<TSource,TKey>)’ cannot be inferred from the usage. Try specifying the type arguments explicitly.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp6
{
    internal class Program
    {
        static void Main(string[] args)
        {
            List<Test> list = new List<Test>
            {
                new Test { Grade = "C", Name = "apple1", Number = 10 },
                new Test { Grade = "C", Name = "apple2", Number = 90 },
                new Test { Grade = "C", Name = "apple3", Number = 30 },
                new Test { Grade = "B", Name = "orange1", Number = 12 },
                new Test { Grade = "B", Name = "orange2", Number = 31 },
                new Test { Grade = "A", Name = "pineapple1", Number = 63 },
                new Test { Grade = "A", Name = "pineapple2", Number = 13 },
                new Test { Grade = "A", Name = "pineapple3", Number = 23 },
                new Test { Grade = "A", Name = "pineapple4", Number = 93 },
                new Test { Grade = "A", Name = "pineapple5", Number = 463 },
                new Test { Grade = "A", Name = "pineapple6", Number = 14 },
                new Test { Grade = "D", Name = "watermelon", Number = 74 }
            };

            //

            //CS0411
            //The type arguments for method cannot be inferred from the usage.
            //Try specifying the type arguments explicitly.
            var aaa = list.GroupBy(x => x.Grade, x => (x.Name, x.Number))
                .Where(g => g.Count() >= 1)
                .OrderByDescending(g => g.Count())
                .ThenBy(g => g.Select(a => a.Number).ToList().Sort((x, y) => x.CompareTo(y)))
                .ToList();

            //expected answers
            //{ Grade = "A", Name = "pineapple2", Number = 13 }
            //{ Grade = "A", Name = "pineapple6", Number = 14 }
            //{ Grade = "A", Name = "pineapple3", Number = 23 }
            //{ Grade = "A", Name = "pineapple1", Number = 63 }
            //{ Grade = "A", Name = "pineapple4", Number = 93 }
            //{ Grade = "A", Name = "pineapple5", Number = 463 }
            //{ Grade = "C", Name = "apple1", Number = 10 }
            //{ Grade = "C", Name = "apple3", Number = 30 }
            //{ Grade = "C", Name = "apple2", Number = 90 }
            //{ Grade = "B", Name = "orange1", Number = 12 }
            //{ Grade = "B", Name = "orange2", Number = 31 }
            //{ Grade = "D", Name = "watermelon", Number = 74 }
        }
    }
    class Test
    {
        public string Grade { get; set; }
        public string Name { get; set; }
        public int Number { get; set; }
    }
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

I want to group using Grade and sort in descending order based on the number of elements in each group, then use the Number property to sort each group element in ascending order.

That’s not what ThenBy is for. ThenBy provides a secondary ordering for the same sequence. It’s not meant to perform a sort within items in the sequence. (Additionally, the last part of your lambda expression in ThenBy is List<T>.Sort, which returns void… whereas the compiler expects a delegate that returns "the thing you want to perform secondary ordering by".)

The "outer sequence" ends up being a sequence of groups. If you want to transform each of those groups, you need to use Select. So I suspect you want:

var aaa = list.GroupBy(x => x.Grade, x => (x.Name, x.Number))
    // Order the groups by descending size of group
    .OrderByDescending(g => g.Count())
    // Order the elements of each individual group by number
    .Select(group => group.OrderBy(a => a.Number).ToList())
    .ToList();

Note: I removed the Where clause as GroupBy never yields any empty groups.

Alternatively, given that the elements of a group returned by GroupBy are the same as in the original sequence, you could order the original sequence by number first:

var aaa = list
    .OrderBy(x => x.Number)
    .GroupBy(x => x.Grade, x => (x.Name, x.Number))
    .OrderByDescending(g => g.Count())
    .ToList();

That way you still end up with a sequence of IGrouping elements, instead of just a sequence of lists… which means you can still access the key for each group.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading