jonsca 1,059 Quantitative Phrenologist Team Colleague Featured Poster

You can and should use v.Last() instead of v.ElementAt(v.Count()-1) . Using v.Last() also only iterates through the collection once, which is sometimes something to be aware of (and sometimes a needless microoptimization) and anyway it's less code.

No, I wasn't aware of that, it's good to know.

Edit: And I think you have it all wrong. Your code groups by the X value and sorts the collection of groups by the groups' first Y values. That's what you want?

Er, actually not in theory. The current query seemed to work but maybe it was coincidence. I wanted to sort the Y values (descending) for each group of X values, then choose the first X,Y value (therefore the furthest down on the screen) to feed to another method. Perhaps I'm still confused about the IEnumerables that emerge from the LINQ query and how to access them properly.

jonsca 1,059 Quantitative Phrenologist Team Colleague Featured Poster

Nice! Thanks so much. Here's what I ended up with(I had to make some minor adjustments, but otherwise worked like a charm):

var Column = from all in invaders group all by all.Location.X into grpResult orderby grpResult.ElementAt(0).Location.Y descending select grpResult;

foreach (var v in Column)
Console.WriteLine(v.ElementAt(v.Count()-1).Location.ToString());

Thanks to Ramy, also.

jonsca 1,059 Quantitative Phrenologist Team Colleague Featured Poster

Here's the class (it's a game of space invaders from Head First C#)

public class Invader
    {  //see directionandtypeenum.cs for Type definition
        private const int HorizontalInterval = 10;
        private const int VerticalInterval = 25; //40;

        private Bitmap image;
        private Point location;
        public Point Location { get { return location; } }  //changed this to make life easier
        public Type InvaderType { get; private set; }

        public Rectangle Area { get { return new Rectangle(location, image.Size); } }

        public int Score { get; private set; }
        public Invader(Type InvaderType,Point location,int score)
        {
            this.InvaderType = InvaderType;
            this.location = location;
            this.Score = score;
            image = InvaderImage(0);
        }

        public void Draw(Graphics g,int animationCell)
        {
            
            g.DrawImage(InvaderImage(animationCell), Location);
        }

        public void Move(Direction direction)
        {
            switch (direction)
            {
                case Direction.Down:
                    location.Y += VerticalInterval;
                    break;
                case Direction.Left:
                    location.X -= HorizontalInterval;
                    break;
                case Direction.Right:
                    location.X += HorizontalInterval;
                    break;
                default: break;
                
            }
        }

        private Bitmap InvaderImage(int animationCell)
        {
            return (Bitmap)Properties.Resources.ResourceManager.GetObject(InvaderType.ToString().ToLower() + (animationCell+1).ToString());
                        
        }
    }

Here's where the query happens in another class called Game (there's a bit more to the method but it's not relevant). The second query as it is doesn't compile...

private void FireInvaderShots()
        {
            if (invaderShots.Count <=2)
            {
                
                var Column = from inv in invaders
                             group inv by inv.Location.X into g
                             select g;
                //into invadergroup             
                //orderby invadergroup.Key descending
                             
                
                
                
                var cols = from v in Column
                            where v.ElementAt(v.Key).Location.Y == v.ElementAt(v.Key).Location.Y.Max()
                            select v;
                
                List<Invader> col = new List<Invader>();
jonsca 1,059 Quantitative Phrenologist Team Colleague Featured Poster


On two phases

var colGrouped = from le in mylist
group le by le.X select le;   <-----*  
var colOrdered = from colGrouped ..... orderby...

Unfortunately this(*) doesn't want to compile without the into

jonsca 1,059 Quantitative Phrenologist Team Colleague Featured Poster

I thought that's what I did... could you be more specific? Do you mean to try forgoing the "into g" step?

Thanks!

jonsca 1,059 Quantitative Phrenologist Team Colleague Featured Poster

I'm having a hard time geting access to properties in the var output of the query (I know I can use foreach on the result that I've got but I'm not sure which elements values I'm accessing). I think my query is just plain wrong, so I'd appreciate some help.

I have a class which contains a Point struct (X,Y). I want to group all of the objects by their X value, and then arrange each of those groups in descending order by the Y values within them. I can get the grouping just fine, but placing the values into the group seems to block me from doing any further computations with them.

Here is my LINQ query:

var col = from le in mylist
	          group le by le.X into g         
			  orderby g.Key descending
			  select g;

at the end of the "group.... into g" line, le goes out of scope so I can't get access to the Y component anymore.
This code currently gives me a group of collections sorted by their X value. I've even tried joining it with the original data set so I could just get a set of (X,Y) values back.

So my question is twofold, how can I "get" my Y values out of the the "g" list or how could I reformulate my query better in the first place...

Thanks much for any help!