Marko Juvančič
Marko Juvančič

Reputation: 5890

Linq group by bahaving strangely

I have a simple list of int with three elements, all of them are set to 1000. If I group this list by values, I still get three elements instead of just one. Why?

var l = new List<int> {1000, 1000, 1000};
var gr = from i in l
         group i by new
            {
                j = i
            }
            into g1
            from g in g1
            select new
            {
                Id = g1.Key.j
            };

var count = gr.Count(); // <- count is 3!

Upvotes: 3

Views: 85

Answers (4)

Paul
Paul

Reputation: 1483

I think you're trying to achieve this:

        var l = new List<pairs>
        {
            new pairs {Index = 0, Value = 1000},
            new pairs {Index = 1, Value = 1000},
            new pairs {Index = 2, Value = 1000},
        };

        var gr = l.GroupBy(a => a.Value);

        var count = gr.Count(); // <- count is 1

Where Pairs is a simple POCO:

internal class pairs
{
    public int Value { get; set; }

    public int Index { get; set; }
}

Upvotes: 1

Rahul Singh
Rahul Singh

Reputation: 21815

That's because you are again projecting the grouped items. It is returning IEnumerable<IGrouping<int,int>> and you are enumerating IEnumerable<int> with from g in g1 which means you will get the items which are in group 1000 and thus the count 3.

Following query will give you correct result:-

var gr = from i in l
         group i by i
         into g1
         select new
         {
             Id = g1.Key
         };

gr.Count() will be 1 here since we are projecting the Key and not the items inside that group.

With Method Syntax:

You currect query is : l.GroupBy(x => x).SelectMany(x => x) so it will project all the items in the group thus Count 3.

If you want to count the Key then: l.GroupBy(x => x).Select(x => x.Key) this will return 1 since it will create a single group of 1000.

Upvotes: 2

kbaccouche
kbaccouche

Reputation: 4605

Loose the second from

var l = new List<int> {1000, 1000, 1000};
var gr = from i in l
     group i by new
        {
            j = i
        }
        into g1
        select new
        {
            Id = g1.Key.j
        };

var count = gr.Count(); // <- count is 1!

Upvotes: 3

DavidG
DavidG

Reputation: 119017

The group by clause gives you the key along with all of the items that are in the group. You are selecting the items and not the key.

For example, try this:

var gr = from i in l
         group i by i into g1
         select g1;

var count = gr.Count();
var itemCount = gr.First().Count();

Upvotes: 0

Related Questions