Reverse the order of nested IObservables

I would like to change the arrangement of a pair of nested IObservableswith several restrictions on the path in which this happens.

As a specific (albeit slightly contrived) example, suppose there is a game server that hosts consecutive online multiplayer games. Players can participate at any time and perform actions in each game. The following classes have working implementations that provide a view of only the actions performed by players during subsequent games:

class GameServer
{
  public IObservable<Game> Games { get { ... } }
}

class Game
{
  public int GameId { get { ... } }
  public IObservable<GamePlayer> Players { get { ... } }
}

class GamePlayer
{
  public int PlayerId { get { ... } }
  public IObservable<PlayerAction> PlayerActions { get { ... } }
}

Inside these classes there is a nested observable IObservable<IObservable<IObservable<PlayerAction>>>. It gives information on the form: There are a series of games. Within each game a series of players joined. Each player performed a number of actions in the game.

, , : There are a number of players. Since each player joined, a series of games have been played. Within each game, the player performed a number of actions. :

IObservable<Player> Players { get; }

:

class Player
{
  public Player(int playerId, IObservable<PlayerGame> games)
  {
    PlayerId = playerId;
    Games = games;
  }

  public int PlayerId { get; private set; }
  public IObservable<PlayerGame> Games { get; private set; }
}

class PlayerGame
{
  public PlayerGame(int gameId, IObservable<PlayerAction> gameActions)
  {
    GameId = gameId;
    GameActions = gameActions;
  }

  public int GameId { get; private set; }
  public IObservable<PlayerAction> GameActions { get; private set; }
}

, , , .

. , , , (.. , Player - PlayerGame, , GameActions ).

Players GameServer.Games ?

( DaveSexton: , , , . GameServer, Game GamePlayer. , Player.)

, , , . , GameServer.Games Game, Player.Games, , PlayerGame ( ).

Players = gameServer.Games
  .Select(g => g.Players.Select(p => new { g.GameId, p.PlayerId, p.PlayerActions }))
  .Switch()
  .GroupBy(t => t.PlayerId)
  .Select(
    group => 
    new Player(group.Key, group.Select(t => new PlayerGame(t.GameId, t.PlayerActions))));
+4
1

, OP.

Players  = Games.Publish(publishedGames => 
             from game in publishedGames
             from player in game.Players
             select new Player(
               player.PlayerId, 
               (from game2 in publishedGames
                from player2 in game2.Players
                where player2.PlayerId == player.PlayerId
                select new PlayerGame(game2.GameId, player2.PlayerActions))
                .StartWith(new PlayerGame(game.GameId, player.PlayerActions))))
           .Distinct(player => player.PlayerId)

SelectMany. Game GamePlayer Player.

, Player GamePlayer. , , , PlayerGame Game; , , ID . .

Publish , Games . , Publish.

Distinct, , a Game , , .

+3

All Articles