2009-11-18 3 views
0

J'essaie de représenter un tableau de bord pour une compétition et je suis aux prises avec les meilleures structures de données à utiliser.Quelles structures de données puis-je utiliser pour représenter une matrice de données 2D fortement typée dans .Net?

J'ai une liste des objets Player, une liste des objets Round, et pour chaque combinaison, je dois stocker un objet RoundScore (il y a différentes parties au score pour un tour).

Ce que je voudrais est une Scoreboard globale objet où ce qui suit est:

1 - Je peux accéder à une collection d'objets identifiés par RoundScoreRound clés en fournissant un objet Player. Par exemple, peut-être quelque chose comme:

public IDictionary<Round,RoundScore> PlayerScores(Player player) { ... } 

2 - Je peux accéder à une collection d'objets identifiés par RoundScorePlayer clés en fournissant un objet Round. par exemple:

public IDictionary<Player,RoundScore> RoundScores(Round round) { ... } 

3 - Je peux accéder à un seul objet RoundScore en fournissant un Player et un Round

4 - Je peux ajouter un nouveau Round et tous Players aura une nouvelle RoundScore pour ce tour avec défaut valeurs

5 - de même, je peux ajouter une nouvelle Player et tous Rounds aura un nouveau RoundScore pour ce joueur avec des valeurs par défaut


Je suppose que ce que je suis vraiment pour une représentation d'une grille avec Rounds sur un axe, Players de l'autre, et RoundScores au milieu.

Y a-t-il déjà une structure de données (ou une combinaison de structures de données) dans .Net que je peux utiliser ou devrais-je utiliser la mienne?

+0

Vous pouvez ajouter un nouveau joueur qui aura un score à chaque tour: vous aurez aussi besoin de traiter un cas d'un cycle dans lequel un ou plusieurs joueurs sont absents: (c'est-à-dire qu'on pourrait être expulsé du jeu, un autre mis à l'écart par une blessure, un autre pourrait l'avoir remplacé par un autre, etc.)? A mon sens, il est bon de définir explicitement les types d'accès les plus fréquents aux données: vous optimisez donc ces types d'accès.Si vous allez obtenir des milliers de demandes pour un score total par joueur, mais peu de demandes pour qui a joué dans un tour donné, à mon humble avis, cela devrait influencer le design. best, – BillW

+0

Si un joueur est absent pour un tour, il y a des règles qui définissent les valeurs dans le RoundScore de ce joueur pour ce round. En d'autres termes, il n'y aura pas d'entrées manquantes dans cette * Matrice * Les opérations les plus fréquentes consisteront à construire cet objet à partir d'entrées de la base de données et à transformer l'objet en une table HTML. Je n'ai pas besoin de gérer les substitutions, et je parle de <100 joueurs avec <100 rounds. – Damovisa

Répondre

4

Je crois que vous devrez rouler les vôtres. Vous pouvez stocker votre matrice de données dans l'un de ces derniers:

List<List<RoundScore>> 

Puis, en ronde, ajouter un champ qui stocke l'index des scores de ce tour. De même, dans Player, ajoutez un champ pour les scores de ce joueur.

Si les lignes sont les scores d'un tour, le retour de cette liste est trivial. Pour retourner la liste des scores pour un joueur, vous pouvez créer une classe qui implémente IList, qui sait comment accéder aux scores par index. En faisant cela, vous n'avez pas besoin de copier les scores dans une nouvelle liste chaque fois qu'ils sont demandés.

Par exemple:

List<Player> Players; 
List<Round> Rounds; 
List<List<RoundScore>> Scores; 


List<RoundScore> GetRoundScores(Round round) 
{ 
    return Scores[round.Index]; 
} 

IList<RoundScore> GetRoundScores(Player player) 
{ 
    return new PlayerScoreList(Scores, player.Index); // or better yet, cache this 
} 


public class PlayerScoreList : IList<RoundScore> 
{ 
    private List<List<RoundScore>> _scores; 
    private int _playerIndex; 

    public RoundScore this[int index] 
    { 
     get 
     { 
      return _scores[_playerIndex][index]; 
     } 
     set 
     { 
      _scores[_playerIndex][index] = value; 
     } 
    } 

    public PlayerScoreList(List<List<RoundScore>> scores, int playerIndex) 
    { 
     _scores = scores; 
     _playerIndex = playerIndex; 
    } 

    public void Add(RoundScore item) 
    { 
     throw new NotSupportedException(); 
    } 

    public void Clear() 
    { 
     throw new NotSupportedException(); 
    } 

    public bool Contains(RoundScore item) 
    {    
     for (int i = 0; i < Count; i++) 
     { 
      if (this[i].Equals(item)) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 

    public int Count 
    { 
     get { return _scores[0].Count; } 
    } 

    public IEnumerator<RoundScore> GetEnumerator() 
    { 
     for (int i = 0; i < Count; i++) 
     { 
      yield return this[i]; 
     } 
    } 

    // ... more methods 

} 
+0

Merci, j'aime ce que vous faites, mais les valeurs de retour que je reçois vont juste être une liste de partitions plutôt qu'un dictionnaire. Il semble que votre code devrait être facile à modifier pour obtenir cela pour moi. Merci. – Damovisa

+0

Oui. Vous pouvez facilement implémenter un IDictionary de la même manière que IList. –