Assuming you have the following lists:
List<ValidGame> validGames;
List<Game> games;
I would suggest something along the lines of:
- For each
Game
object in games
, creating a collection of 'platform and game ID' objects
(resulting in one created object per Platform
object in the Game
's Platforms
)
- Flattening the generated collections into one big collection
- Grouping the 'platform and game ID' object collection by platform type and version
- Creating a dictionary where the
Platform
object is the key, and a collection of the game IDs of the games that are already on that platform is the value
- For each entry in the dictionary, evaluate which game IDs are missing
For a simple example (with simplified GUID
values), let's say games
contains two objects:
{
Id: ABC
Name: "GameA"
Platforms:
[
{ PlatformType: Android, Version: "V1" },
{ PlatformType: Android, Version: "V2" },
]
},
{
Id: DEF
Name: "GameB"
Platforms:
[
{ PlatformType: Android, Version: "V1" },
{ PlatformType: iOS, Version: "V1" },
]
},
The results of step 1--4 would look roughly like the following:
Result of step 1 + 2: Collection
--------------------------------
{ ( Platform: { PlatformType: Android, Version: "V1" }, GameId: ABC ) },
{ ( Platform: { PlatformType: Android, Version: "V2" }, GameId: ABC ) },
{ ( Platform: { PlatformType: Android, Version: "V1" }, GameId: DEF ) },
{ ( Platform: { PlatformType: iOS, Version: "V1" }, GameId: DEF ) },
Result of step 3: Grouping
--------------------------
{ Key: "Android_V1":
{ ( Platform: { PlatformType: Android, Version: "V1" }, GameId: ABC ) },
{ ( Platform: { PlatformType: Android, Version: "V1" }, GameId: DEF ) },
},
{ Key: "Android_V2":
{ ( Platform: { PlatformType: Android, Version: "V2" }, GameId: ABC ) },
},
{ Key: "iOS_V1":
{ ( Platform: { PlatformType: iOS, Version: "V1" }, GameId: DEF ) },
}
Result of step 4: Dictionary of game IDs already present on each platform
-------------------------------------------------------------------------
{
Key: { PlatformType: Android, Version: "V1" },
Value: { ABC, DEF }
},
{
Key: { PlatformType: Android, Version: "V2" },
Value: { ABC }
},
{
Key: { PlatformType: iOS, Version: "V1" },
Value: { DEF }
},
Without having verified it in an IDE, the implementation of step 1--4 could be roughly as follows:
Dictionary<Platform, IEnumerable<Guid>> gameIdsPerPlatform = games
// Step 1--2:
.SelectMany(game => game.Platforms
.Select(platform => (Platform: platform, GameId: game.Id)))
// Step 3:
.GroupBy(platformAndGameId =>
$"{platformAndGameId.Platform.PlatformType}_{platformAndGameId.Platform.Version}")
// Step 4:
.ToDictionary(
gr => gr.First().Platform,
gr => gr.Select(platformAndGameId => platformAndGameId.GameId));
Here, several methods from the System.Linq
namespace are used:
In step 5, .ExceptBy()
(also from the System.Linq
namespace) may be used to find which games are missing from each platform:
Dictionary<Platform, List<ValidGame>> missingGamesPerPlatform = gameIdsPerPlatform
.ToDictionary(
kvp => kvp.Key,
kvp => validGames
.ExceptBy(kvp.Value.Select(game => game.Id), validGame => validGame.Id)
.ToList()
);
Note:
This suggested approach assumes that the uniqueness of a game (whether it's an existing game or a valid game) is defined by the Game
's/ValidGame
's Id
value (i.e. if two Game
/ValidGame
objects have identical Name
values, they will also have identical Id
values). If that is a wrong assumption, changes need to be made for this approach to work.