views:

45

answers:

2

I have a List<T> that is holding several objects called tc of type TwitterCollection. Each instance of tc contains 5 properties.

The TwitterCollection class looks like this:

public class TwitterCollection
{
    public string origURL { get; set; }
    public string txtDesc { get; set; }
    public string imgURL { get; set; }
    public string userName { get; set; }
    public string createdAt { get; set; }

}

I am running a Linq to objects statement as such:

    var counts = from tc in sList
                 group tc by tc.origURL into g
                 orderby g.Count()
                 select new { myLink = g.Key, Count = g.Count() };

Now the problem I have is that I can't access any of the tc properties. I can access the origURL no problem, as it is assigned to g... but the txtDesc, imgURL and the other properties seem inaccessible. I need the above statement in order to sort my data appropriately.

How can I modify my Linq statement to include all the other properties of tc, plus for it to still be sorted/ordered by Count() in the way it is now.

Appreciate any help (I'm a relative newbie)... Many thanks in advance.

+1  A: 

The issue is that you've effectively discarded all the items in the group. You need to maintain that information somehow. For example:

var groups = from tc in sList 
             group tc by tc.origURL into g 
             orderby g.Count() 
             select new { myLink = g.Key, Items = g }; 

foreach(var group in groups) {
    Console.WriteLine("Link: {0}, Count: {1}", group.myLink, group.Items.Count());
    foreach(var item in group.Items) {
        Console.WriteLine(item.txtDesc);
    }
}
Jason
I can see that this is very useful too. Many thanks, so Items are my object properties.
AlexW
`Items` are the instances of `TwitterCollection` in `sList` that have `TwitterCollection.origURL` equal to `myLink`.
Jason
+2  A: 

You've grouped the results - so which username would you expect to get? The group is a whole sequence of elements, all with the same URL. If you want to use the first one, you could do something like:

var counts = from tc in sList
             group tc by tc.origURL into g
             orderby g.Count()
             select new { myLink = g.Key, First = g.First(), Count = g.Count() };

You could then do:

foreach (var group in counts)
{
    Console.WriteLine(group.First.userName);
}

If you want the whole group, then just select it:

var counts = from tc in sList
             group tc by tc.origURL into g
             orderby g.Count()
             select new { Group = g, Count = g.Count() };

Admittedly at that point, there's not much point in having Count separately - you could just do:

var groups = sList.GroupBy(tc => tc.origURL)
                  .OrderBy(g => g.Count());

You can then use:

foreach (var group in groups)
{
    int count = group.Count();
    var key = group.Key;
    foreach (var entry in group)
    {
        // Use each item in the group, etc.
    }
}
Jon Skeet
That worked like a dream... First is not a method within Linq I'm familiar with. I will be sure to read up on it right now though. Thanks so much!!
AlexW
I am using one instance from each group so I personally prefer the Group = g, Count = g.Count() approach. Also The second one is a tad confusing as I still haven't got my head round lamdas yet... I will though. BTW I like your online material! great delivery in the talks you give, very accessible and funny.
AlexW