Reputation: 7112
I have this method below that gathers data from different sources and returns it as one IEnumerable.
I'm having trouble though, figuring out how to combine all the sources into one object of type TotalRoomContents.
TotalRoomContents is of type IEnumerable<String>
.
Here is the unfinished method:
public static TotalRoomContents GetRoomContents(this Dungeon dungeon)
{
var customArmor = dungeon.Rooms
.Select(pe => pe.Room)
.Where(e => e.Monster.IsActive);
// check each customArmor object to see if it exists in the MapLookupByRoomId dictionary
if (customArmor != null && MapLookupByRoomId.ContainsKey(customArmor.Id))
// add all item(s) of type customArmor to TotalRoomContents()
if(dungeon.RoomType?.InventoryContent != null)
{
// add item(s) from dungeon.RoomType?.InventoryContent to TotalRoomContents()
}
return new TotalRoomContents()
}
As you can see, I don't know how to add the item(s) to the TotalRoomContents
object.
The items will be from dungeon.RoomType?.InventoryContent
and all the customArmor
objects found in the linq query.
Is there a way to do this in one method or do I need to create some type of other method to do this?
Thanks!
Upvotes: 0
Views: 402
Reputation: 190
Why don't you create a list of "RoomContent" (that represents whatever a room can contain), and start adding all the different results from your other queries?
List<RoomContent> TotalRoomContents = new List<RoomContent>();
if (/* Whatever condition needs to be met */)
{
TotalRoomContents.Add(/* Whatever you may want */);
}
Also, you should know that Linq queries are not executed until the code needs to enumerate it, so, basically you can build a query in steps:
// This is just to simulate the data source
IQueryable<RoomContent> query = allPossibleRoomContents.AsQueryable();
query = query.Where(x => x.ContentDescription = "Sword");
query = query.Where(x => x.ContentDescription = "Axe");
// This is where the actual work is done
return query.ToList();
Hope this helps!
Upvotes: 1
Reputation: 1192
You could create a wrapper class that would take care of this. A possible implementation could look like this
public class AggregateEnumerable<T> : IEnumerable<T> {
private readonly IEnumerable<T>[] _sources;
public AggregateEnumerable( params IEnumerable<T>[] sources ) {
_sources = sources;
}
public IEnumerator<T> GetEnumerator() {
foreach( var source in _sources ) {
var enumerator = source.GetEnumerator();
while( enumerator.MoveNext() )
yield return enumerator.Current;
}
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
And then you would use it like
var firstEnumerable = new[] { "Peter", "John" };
var secondEnumerable = new[] { "Thomas", "George" };
var myEnum = new AggregateEnumerable<string>(firstEnumerable, secondEnumerable);
foreach( var value in myEnum )
Console.WriteLine(value);
Upvotes: 1