943,670 Members | Top Members by Rank

Ad:
  • C# Discussion Thread
  • Marked Solved
  • Views: 1370
  • C# RSS
You are currently viewing page 1 of this multi-page discussion thread
Sep 17th, 2009
0

LINQ - getting IEnumerables

Expand Post »
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:
C# Syntax (Toggle Plain Text)
  1. var col = from le in mylist
  2. group le by le.X into g
  3. orderby g.Key descending
  4. 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!
Sponsor
Featured Poster
Reputation Points: 1165
Solved Threads: 578
Quantitative Phrenologist
jonsca is offline Offline
4,271 posts
since Sep 2009
Sep 17th, 2009
0

Re: LINQ - getting IEnumerables

Try to group first then order second
Featured Poster
Reputation Points: 480
Solved Threads: 276
Postaholic
Ramy Mahrous is offline Offline
2,189 posts
since Aug 2006
Sep 17th, 2009
0

Re: LINQ - getting IEnumerables

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

Thanks!
Sponsor
Featured Poster
Reputation Points: 1165
Solved Threads: 578
Quantitative Phrenologist
jonsca is offline Offline
4,271 posts
since Sep 2009
Sep 17th, 2009
2

Re: LINQ - getting IEnumerables

C# Syntax (Toggle Plain Text)
  1. var col = from le in mylist
  2. group le by le.X into g
  3. orderby g.Key descending
  4. select g;
On two phases
c# Syntax (Toggle Plain Text)
  1. var colGrouped = from le in mylist
  2. group le by le.X select le;
  3.  
  4. var colOrdered = from colGrouped ..... orderby...
Featured Poster
Reputation Points: 480
Solved Threads: 276
Postaholic
Ramy Mahrous is offline Offline
2,189 posts
since Aug 2006
Sep 17th, 2009
0

Re: LINQ - getting IEnumerables


On two phases
c# Syntax (Toggle Plain Text)
  1. var colGrouped = from le in mylist
  2. group le by le.X select le; <-----*
  3. var colOrdered = from colGrouped ..... orderby...
Unfortunately this(*) doesn't want to compile without the into
Sponsor
Featured Poster
Reputation Points: 1165
Solved Threads: 578
Quantitative Phrenologist
jonsca is offline Offline
4,271 posts
since Sep 2009
Sep 18th, 2009
0

Re: LINQ - getting IEnumerables

So please send your class code you want to group and order it; the class has this struct to play with this problem.
Featured Poster
Reputation Points: 480
Solved Threads: 276
Postaholic
Ramy Mahrous is offline Offline
2,189 posts
since Aug 2006
Sep 19th, 2009
0

Re: LINQ - getting IEnumerables

Here's the class (it's a game of space invaders from Head First C#)
C# Syntax (Toggle Plain Text)
  1. public class Invader
  2. { //see directionandtypeenum.cs for Type definition
  3. private const int HorizontalInterval = 10;
  4. private const int VerticalInterval = 25; //40;
  5.  
  6. private Bitmap image;
  7. private Point location;
  8. public Point Location { get { return location; } } //changed this to make life easier
  9. public Type InvaderType { get; private set; }
  10.  
  11. public Rectangle Area { get { return new Rectangle(location, image.Size); } }
  12.  
  13. public int Score { get; private set; }
  14. public Invader(Type InvaderType,Point location,int score)
  15. {
  16. this.InvaderType = InvaderType;
  17. this.location = location;
  18. this.Score = score;
  19. image = InvaderImage(0);
  20. }
  21.  
  22. public void Draw(Graphics g,int animationCell)
  23. {
  24.  
  25. g.DrawImage(InvaderImage(animationCell), Location);
  26. }
  27.  
  28. public void Move(Direction direction)
  29. {
  30. switch (direction)
  31. {
  32. case Direction.Down:
  33. location.Y += VerticalInterval;
  34. break;
  35. case Direction.Left:
  36. location.X -= HorizontalInterval;
  37. break;
  38. case Direction.Right:
  39. location.X += HorizontalInterval;
  40. break;
  41. default: break;
  42.  
  43. }
  44. }
  45.  
  46. private Bitmap InvaderImage(int animationCell)
  47. {
  48. return (Bitmap)Properties.Resources.ResourceManager.GetObject(InvaderType.ToString().ToLower() + (animationCell+1).ToString());
  49.  
  50. }
  51. }

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...
C# Syntax (Toggle Plain Text)
  1. private void FireInvaderShots()
  2. {
  3. if (invaderShots.Count <=2)
  4. {
  5.  
  6. var Column = from inv in invaders
  7. group inv by inv.Location.X into g
  8. select g;
  9. //into invadergroup
  10. //orderby invadergroup.Key descending
  11.  
  12.  
  13.  
  14.  
  15. var cols = from v in Column
  16. where v.ElementAt(v.Key).Location.Y == v.ElementAt(v.Key).Location.Y.Max()
  17. select v;
  18.  
  19. List<Invader> col = new List<Invader>();
Last edited by jonsca; Sep 19th, 2009 at 4:10 am.
Sponsor
Featured Poster
Reputation Points: 1165
Solved Threads: 578
Quantitative Phrenologist
jonsca is offline Offline
4,271 posts
since Sep 2009
Sep 19th, 2009
0

Re: LINQ - getting IEnumerables

Take a look at this code,
C# Syntax (Toggle Plain Text)
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Linq.Expressions;
  6.  
  7. class MainApp
  8. {
  9. static void Main()
  10. {
  11. List<MyData> items = new List<MyData>();
  12. items.Add(new MyData("A", "1"));
  13. items.Add(new MyData("A", "2"));
  14. items.Add(new MyData("B", "3"));
  15. items.Add(new MyData("A", "4"));
  16.  
  17. var result = from all in items group all by all.State into grpResult orderby grpResult.Key descending select grpResult;
  18.  
  19. foreach (var t in result){
  20. Console.WriteLine(t.Key + " " + t.Count());
  21. }
  22. }
  23. }
  24. public class MyData{
  25. public string State { get; set; }
  26. public string City { get; set; }
  27. public MyData() { }
  28. public MyData(string _state, string _city){
  29. State = _state;
  30. City = _city;
  31. }
  32. }
Moderator
Reputation Points: 2136
Solved Threads: 1228
Posting Genius
adatapost is offline Offline
6,527 posts
since Oct 2008
Sep 19th, 2009
0

Re: LINQ - getting IEnumerables

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

C# Syntax (Toggle Plain Text)
  1. var Column = from all in invaders group all by all.Location.X into grpResult orderby grpResult.ElementAt(0).Location.Y descending select grpResult;
  2.  
  3. foreach (var v in Column)
  4. Console.WriteLine(v.ElementAt(v.Count()-1).Location.ToString());

Thanks to Ramy, also.
Sponsor
Featured Poster
Reputation Points: 1165
Solved Threads: 578
Quantitative Phrenologist
jonsca is offline Offline
4,271 posts
since Sep 2009
Sep 19th, 2009
1

Re: LINQ - getting IEnumerables

Click to Expand / Collapse  Quote originally posted by jonsca ...
C# Syntax (Toggle Plain Text)
  1. var Column = from all in invaders group all by all.Location.X into grpResult orderby grpResult.ElementAt(0).Location.Y descending select grpResult;
  2.  
  3. foreach (var v in Column)
  4. Console.WriteLine(v.ElementAt(v.Count()-1).Location.ToString());
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.

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?
Last edited by Rashakil Fol; Sep 19th, 2009 at 8:24 pm.
Team Colleague
Reputation Points: 1133
Solved Threads: 171
Super Senior Demiposter
Rashakil Fol is offline Offline
2,478 posts
since Jun 2005

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C# Forum Timeline: DateTime.. out_of_range
Next Thread in C# Forum Timeline: import from excel to datagridview





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC