Skip Navigation Links
C# Corner Home
Forum Home
Latest 50
Unanswered
Win Prizes
All Time Leaders
Jump to CategoryExpand Jump to Category
Login 
    Welcome Guest!
 Search Forum For :  
X
 Login
Please login to submit a new post, reply and edit exiting posts, see user profiles, and access more features. If you are not a registered member, Register here.
User Id / Email:
Password:  
Forgot Password | Forgot UserName
   Home » LINQ » Combining multiple sequences into 1 object
       
Author Reply
Rich
posted 44 posts
since Oct 05, 2011 
from

Combining multiple sequences into 1 object

  Posted on: 04 Feb 2012       
What is the correct way to iterate through several sequences/list etc., and combine them respectively in an object.  For example, I have a list of teams, and two different lists of stats. I would like to combine the two list of stats with the respective team in the list of teams and that to a class.  Hope this makes since.  Thanks in advance.
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 04 Feb 2012   Accepted Answer     0  
Assuming that the sequences are already in the correct order, then something like this is probably easiest and should scale OK to more that 3 sequences:

using System;
using System.Collections.Generic;
using System.Linq;

class Team
{
  public string Name {get; set;}
  public int Stat1 {get; set;}
  public int Stat2 {get; set;}

  public Team(string name, int stat1, int stat2)
  {
     Name = name;
     Stat1 = stat1;
     Stat2 = stat2;
  }

  public override string ToString()
  {
     return String.Format("Name = {0}, Stat1 = {1}, Stat2 = {2}", Name, Stat1, Stat2);
  }
}

class Program
{
   static void Main()
   {
      List<string> teams = new List<string>{"team1", "team2", "team3"};
      List<int> stats1 = new List<int>{100, 90, 80};
      List<int> stats2 = new List<int>{85, 75, 95};

      List<Team> teamList = teams.Select((t, i) => new Team(t, stats1[i], stats2[i])).ToList();

      foreach(Team team in teamList) Console.WriteLine(team);
      Console.ReadKey();
   }
}

Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 04 Feb 2012        0  
Vulpes, thanks for the response.  I will try this out shortly, but as I am new to programming, I have a question about the lamda expression associated with the list<Team>teamList.  What do the parameters t and i represent in   teams.Select((t, i) => new Team(t, stats1[i], stats2[i])).ToList(); ?
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 04 Feb 2012        0  
't' represents each string in the 'teams' list and 'i' represents its index in that list.

So, for the first element, 't' will "team1" and 'i' will be 0.

We can then use 'i' to read off the stats for a particular team from the other 2 lists. 
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 05 Feb 2012        0  
Vulpes, thanks! Your answer helped me out and I have a much better understanding of the lambda expression. 
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 06 Feb 2012        0  
Vulpes, I have another related question.  I am now trying to figure out how to perform calculations on a list of objects, and then put the results in a new list.  for example:

List<OffenseStats> off = new List<OffenseStats>
{
        new OffenseStats {Team= "Bears", FGA = 50, FGM = 25},
        new OffenseStats {Team= "Lions", FGA = 70, FGM = 20}
};

How can I then create the equation FGM/FGA for each team, and then put the results in a new List:

List<GoalPercent> GoalPercent = ?????

The GoalPercent class would look something like this:

class GoalPercent()
{
        public string Team {get; set;}
        decimal GoalPercent {get; set;}

public GoalPercent(string team, decimal gp)
{
        Team = team;
        GoalPercent = gp;
}

}

Thanks in advance.
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 06 Feb 2012        1  
Off the top of my head, I'd say:

List<GoalPercent> GoalPercent = off.Select( o => new GoalPercent(o.Team, (decimal)o.FGM/o.FGA * 100m) ).ToList();
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 06 Feb 2012        0  
That did it thanks!  I really appreciate your help.  Do you have a twitter account that I can follow?
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 07 Feb 2012        0  
Afraid not, Rich.

The only 'tweeting' I do is on here :)
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 10 Feb 2012        0  
Vulpes, I have yet another problem that I am having trouble with.  I have this class:

public class NBASeason
{
        public int Season {get;set;}
        public datetime date {get;set;}
        public string awayTeam {get;set;}
        public int awayScore {get;set;}
        public string homeTeam {get;set;}
        public int homeScore {get;set;}
}

I basically want to calculate each away team's win/loss record, and place it in another class such as:

class AwayRecord
{
        public string AwayTeam {get;set;}
        public int Wins {get;set}
        public int Losses {get;set}
}
I have already made a list that queried the winning away teams:

 List<Season> w = this.NBAGetSeasonScores().Where(atw => atw.awayScore > atw.homeScore)  .OrderBy(away => away.away).AsEnumerable().ToList();

From this point, I suspect a lambda GroupBy extension method may be needed, as the awayTeam property in the Season class will contain several copies of the same team, but I have yet to correctly figure this out. Hope this makes since. Thanks in advance.
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 11 Feb 2012        1  
TBH, Rich, it doesn't make complete sense because what you've called a Season seems to me to be a Game and, in any case, a Season class can't have a property of the same name.

Also, I'd have thought that your AwayRecord class needs an additional property for the name of the team (Team say) and I wasn't clear what the date property was storing unless it's the date of the first away game for that team.

Anyway, for now, I've ignored the Season and date properties and just populated the others with this query which, as you suspected, requires the GroupBy extension method:

List<AwayRecord> awayRecords = this.NBAGetSeasonScores().
GroupBy(s => s.awayTeam).OrderBy(g => g.Key).Select(g => new AwayRecord{Team = g.Key, Wins = g.Count(s => s.awayScore > s.homeScore), Losses = g.Count(s => s.awayScore < s.homeScore)}).AsEnumerable().ToList();
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 11 Feb 2012        0  
Vulpes, yeah thanks for pointing out those errors.  I went back and made updates to the post.  Season would be the year such as 1980. The date property represents the date of the game played. Your example makes since, and I think it should work.  I'll try to implement it shortly and let you know the result.   I really appreciate your insight and time.  As a new programmer, it helps me out to see real world examples of the language in action. 
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 13 Feb 2012        0  
Vulpes, your query worked like a charm.   I have yet created another challenge for myself.  I added two more properties to the AwayRecord class, which are Spread and Total.  The Spread property should hold the average point amount an away team wins or looses by(awayScore - homeScore), while the Total property should hold the average point total of the game(awayScore + homeScore).  The Total property was easy enough, but I am having trouble trying to figure out how to correctly query for the Spread property, since the away team isn't always a winner, therefore producing unwanted negative results( awayScore 80 - homeScore 100).  I am guessing this may involve a nested lambda expression, and possibly creating another class.  Here is what I have so far:

// Get NBA Away Record
        public List<NBAawayRecord> NBAteamAwayRecord()
        {
            List<NBAawayRecord> AwayRecord = this.NBAGetSeasonScores().GroupBy(at => at.away)
                .OrderBy(g => g.Key).Select(g => new NBAawayRecord
                {
                    Teams = g.Key,
                    Wins = g.Count(at => at.awayScore > at.homeScore)
                    ,
                    Losses = g.Count(at => at.awayScore < at.homeScore)
                    ,
                    Spread = g.Average(?????)
                    ,
                    Total = g.Average(at => (decimal)at.awayScore + (decimal)at.homeScore)
                }).AsEnumerable().ToList();
 
            return AwayRecord;
 
        }
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 13 Feb 2012        1  
To convert the negative values into positive values, all you need to do is to use the absolute value of the difference in scores:

Spread = g.Average(at => (decimal)Math.Abs(at.awayScore - at.homeScore))

Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 13 Feb 2012        0  
worked perfectly, but for some reason I had to move the casting, though:

Spread = g.Average(at => Math.Abs((decimal)at.awayScore - (decimal)at.homeScore))
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 14 Feb 2012        0  
Don't understand that as (at.awayScore - at.homeScore) is integral and Math.Abs has an overload for Int32 as well as Decimal.

Might be a LINQ to SQL peculiarity but no matter if it's OK working for you :)
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 14 Feb 2012        0  
Vulpes,  have you thought about writing an article on these type of LINQ scenarios?  Particularly on LINQ extension methods involving calculations based on properties from different sequences, objects, etc.  I've searched the web, and can only fine basic LINQ examples to learn from, but nothing as specific as what you have taught me thus far.  I think a lot of new programmers such as myself would really benefit from such an article.
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 15 Feb 2012        0  
I have a number of ideas for future articles but, unfortunately, I don't have the time to write them just now :(

A problem with writing an article about something like this is that you need to have a basic grasp of LINQ in order to be able to understand it and I'm not sure that many C# developers do.

Anyway, thanks for the idea, and I'll add it to the list :)
Rich
posted  44 posts
since  Oct 05, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 17 Feb 2012        0  
Vulpes, the following code works for me perfectly, but I am wondering if there is a more concise or efficient way of obtaining the desired results.

public List<NBAstandings> NBAgetStandings()
        {
            List<nba_Team_Names> teams = this.NBAgetTeams().AsEnumerable().OrderBy(t => t.Abreviated_Long)
                .Select(t => t).ToList();

            List<NBAstandings> AwayRecord = this.NBAGetSeasonScores().GroupBy(ar => ar.away)
                .OrderBy(t => t.Key).Select(t => new NBAstandings
                {
                    Teams = t.Key,
                    Wins = t.Count(at => at.awayScore > at.homeScore),
                    Losses = t.Count(at => at.awayScore < at.homeScore),
                    Spread = t.Sum(at => Math.Abs((decimal)at.awayScore - (decimal)at.homeScore)),
                    Total = t.Sum(at => (decimal)at.awayScore + (decimal)at.homeScore)
                }).AsEnumerable().ToList();

            List<NBAstandings> HomeRecord = this.NBAGetSeasonScores().GroupBy(hr => hr.home)
                .OrderBy(t => t.Key).Select(t => new NBAstandings
                {
                    Teams = t.Key,
                    Wins = t.Count(ht => ht.homeScore > ht.awayScore),
                    Losses = t.Count(ht => ht.homeScore < ht.awayScore),
                    Spread = t.Sum(ht => Math.Abs((decimal)ht.homeScore - (decimal)ht.awayScore)),
                    Total = t.Sum(ht => (decimal)ht.homeScore + (decimal)ht.awayScore)
                }).AsEnumerable().ToList();

            List<NBAstandings> TotalSeason = teams.Select((t, i) => new NBAstandings
                (t.Abreviated_Long, AwayRecord[i], HomeRecord[i])).ToList();

            return TotalSeason;
        }


public class NBAstandings
    {
        public string Teams { get; set; }
        public int Wins { get; set; }
        public int Losses { get; set; }
        public decimal Spread { get; set; }
        public decimal Total { get; set; }
        public NBAstandings AR { get; set; }
        public NBAstandings HR { get; set; }

        // Constructors
        public NBAstandings()
        {}

        public NBAstandings(string teams, NBAstandings ar, NBAstandings hr)
        {
            Teams = teams;
            Wins = ar.Wins + hr.Wins;
            Losses = ar.Losses + hr.Losses;
            Spread = (ar.Spread + hr.Spread)/(ar.Wins + hr.Wins
                + ar.Losses + hr.Losses);
            Total = (ar.Total + hr.Total)/(ar.Wins + hr.Wins + ar.Losses + hr.Losses);
        }

    }
}
Vulpes
posted  5419 posts
since  Feb 28, 2011 
from 

 Re: Combining multiple sequences into 1 object
  Posted on: 18 Feb 2012        0  
In your first query:

List<nba_Team_Names> teams = this.NBAgetTeams().AsEnumerable().OrderBy(t => t.Abreviated_Long).Select(t => t).ToList();

you could omit the Select() method which isn't actually doing anything:

List<nba_Team_Names> teams = this.NBAgetTeams().AsEnumerable().OrderBy(t => t.Abreviated_Long).ToList();

but other than that it's fine.

I woudn't try to cram too much into your LINQ queries as it makes them harder to understand and to maintain. I thought these seemed just right :) 
       
Nevron Gauge for SharePoint
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications. Visit DynamicPDF here
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites - Click Here!
Team Foundation Server Hosting
 Hosted by MaximumASP  |  Found a broken link?  |  Contact Us  |  Terms & conditions  |  Privacy Policy  |  Site Map  |  Advertise with us
Current Version: 5.2011.3.12
 © 1999 - 2012  Mindcracker LLC. All Rights Reserved