2017-04-27 4 views
0

J'ai un problème. Je fais un programme de tournoi de tennis pour un projet d'école. Nous sommes censés utiliser des fichiers txt, où ils sont lus et nous devons être en mesure d'extraire un certain nombre de joueurs, cela va être utilisé pour la simulation du tournoi.Récupère un certain nombre de lignes d'un fichier txt dans une liste.

public class ReadPlayers 
{ 
    private List<ReadFiles> players = new List<ReadFiles>(); //Opretter en liste af strenge. 
    public string FileName { get; set; } 
    public string Delimiter { get; set; } 
    public ReadPlayers(string fn, string delim = "|") //Konstruktur 
    { 
     FileName = fn; 
     Delimiter = delim; 
    } 

    public override string ToString() 
    { 
     var rv = ""; 

     foreach (var c in players) 
      rv += c + "\n"; 
     return rv; 
    } 

    public void Load() 
    { 
     TextFieldParser par = new TextFieldParser(FileName, Encoding.GetEncoding("iso-8859-1")); 
     par.TextFieldType = FieldType.Delimited; 
     par.SetDelimiters(Delimiter); 
     while (!par.EndOfData) 
     { 
      string[] fields = par.ReadFields(); 
      string FirstName = fields[1]; 
      string MiddleName = fields[2]; 
      string LastName = fields[3]; 
      DateTime DateOfBirth = DateTime.ParseExact(fields[4], "yyyy-MM-dd", CultureInfo.InvariantCulture); 
      String Country = fields[5]; 
      string ShortNameCountry = fields[6]; 
      var c = new ReadFiles(FirstName, MiddleName, LastName, DateOfBirth, Country, ShortNameCountry); 
      players.Add(c); 
     } 
     players.Shuffle(); 
     par.Close(); 

Et dans mon principal je charge le fichier et l'imprime. Cela fonctionne parfaitement. Mais je dois être capable d'imprimer seulement 8, 16, 32 ou 64 joueurs de la liste.

+2

_players.Take (16) _ ou _players.Skip (16) .Take (16) _ et ainsi de suite. Paramétrer le 16 et créer une méthode qui renvoie le sous-ensemble – Steve

Répondre

0

Il existe des moyens de le faire.

  1. Déclarez une constante (MAX_PLAYERS) ou une variable pour stocker les MAX_COUNT des joueurs que vous voulez dire 8, 16, 32 ou 64. Déclare un compteur et l'incrémenter dans la boucle while. Une fois le compteur atteint, quittez la boucle. Ici, vous obtiendrez seulement le 1er ou le 8ème fichier du formulaire qui vous intéresse. Pas besoin de lire le fichier complet lorsque tous les enregistrements ne sont pas intéressés.

while (!par.EndOfData && counter < MAX_PLAYERS)

  1. Vous avez utilisé la déclaration players.Shuffle();. Donc, il suffit de choisir le top MAX_PLAYERS de la liste après le brassage. Cela rend plus logique que vous conservez la liste complète des joueurs et aussi la liste sélectionnée parmi eux.

var selectedList = players.Take(MAX_PLAYERS);

+0

A travaillé génial! Merci: D – Catchybatchy

+0

@Catchybatchy, Si cela a fonctionné, veuillez le marquer comme une réponse. –

0

Vous pouvez modifier votre méthode ToString() pour recevoir deux paramètres
Le premier est le nombre de joueurs que vous voulez revenir dans la chaîne, le second paramètre est le nombre de joueurs sauter de la liste avant d'obtenir le lot suivant de joueurs.

public string ToString(int takeCount, int skipFirst) 
{ 
    return string.Join(Environment.NewLine, players.Skip(skipFirst).Take(takeCount)); 
} 

Ajouter également une propriété qui vous indique combien de joueurs sont dans la liste

public int NumberOfPlayers 
{ 
    get { return players.Count; } 
} 

de cette façon vous pouvez appeler le ToString dans une boucle et recevoir des lots de joueurs jusqu'à ce que vous atteignez le nombre total des joueurs présents dans la liste

int batchSize = 16; 
for(int i = 0; i < readPlayerInstance.NumberOfPlayers; i+=batchSize) 
{ 
    string players = readPlayerInstance.ToString(batchSize, i) 
    .... show your players in batch of 16 
} 

Bien sûr, au lieu de changer la substitution de la méthode ToString(), vous ajoutez simplement votre propre méthode qui retourne les joueurs en lots dans comme vous aimez et (par exemple) retourner une sous-liste de vos joueurs.

public List<ReadFiles> GetPlayers(int takeCount, int skipFirst) 
{ 
    return players.Skip(skipFirst).Take(takeCount).ToList(); 
} 
1

Vous pouvez utiliser ce qui est connu comme "Reservoir sampling" pour sélectionner un certain nombre d'éléments d'une séquence de longueur inconnue (mais qui doit être suffisamment longue pour fournir tous les articles).

L'algorithme ressemble à ceci:

public static T[] RandomlySelectedItems<T>(IEnumerable<T> items, int n, Random rng) 
{ 
    var result = new T[n]; 
    int index = 0; 
    int count = 0; 

    foreach (var item in items) 
    { 
     if (index < n) 
     { 
      result[count++] = item; 
     } 
     else 
     { 
      int r = rng.Next(0, index + 1); 

      if (r < n) 
       result[r] = item; 
     } 

     ++index; 
    } 

    if (index < n) 
     throw new ArgumentException("Input sequence too short"); 

    return result; 
} 

Notez que le tableau résultant est dans un ordre aléatoire; il ne contient pas d'éléments dans l'ordre où ils sont apparus dans la séquence d'entrée.

Vous pouvez l'utiliser pour sélectionner N lignes au hasard (et dans un ordre aléatoire) à partir d'un fichier texte comme suit:

string filename = "Your filename goes here"; 
var lines = File.ReadLines(filename); 
int n = 16; // Number of lines to select. 
var result = RandomlySelectedItems(lines, n, new Random()).ToList();