Pure.Krome
Pure.Krome

Reputation: 86937

How can I use Linq to extract this data from a List?

I have a list of the following:

Id: Game-1
GameType: Battlefield3
LogEntries: (an IList<LogEntry>)
  - Id: 1, Foo: Blah blah blah..
  - Id: 231, Foo: Blah blah blah..
  - Id: 342321, Foo: Blah blah blah..

Id: Game-2
GameType: Battlefield3
LogEntries: null

Id: Game-1
GameType: Battlefield3
LogEntries: (an IList<LogEntry>)
  - Id: 2121, Foo: Blah blah blah..
  - Id: 21333321, Foo: Blah blah blah..

etc. So each game server can have 0 to many log entries.

Now, i'm trying to get the results in the following format.

IList<LogEntries> logEntries = <some linq magic>

Id: 1, Foo: Blah blah blah..
Id: 231, Foo: ....
Id: 2121, Foo: ....
Id: 342321, Foo: ....
Id: 342321, Foo: ....

So the log entries are ordered by Id.

Upvotes: 1

Views: 127

Answers (1)

Ani
Ani

Reputation: 113402

I think you want:

IList<LogEntries> logEntries = games.SelectMany(game => game.LogEntries ?? Enumerable.Empty<LogEntry>())
                                    .OrderBy(logEntry => logEntry.Id)
                                    .ToList();

The key here is SelectMany operator, which maps each game to its log-entries and flattens the sequence of log-entry sequences to a simple sequence of log-entries.

You can also do this in query syntax:

var logEntries = from game in games
                 from logEntry in game.LogEntries ?? Enumerable.Empty<LogEntry>()                  
                 orderby logEntry.Id
                 select logEntry;

(You can call ToList() on the above to materialize the query to a list).

Personally though, I would change the Game type such that its LogEntries property could never be null, so you don't need to resort to null filtering gymnastics like the ones above.

Upvotes: 7

Related Questions