2017-04-27 57 views
0

我有一個問題。我正在爲一個學校項目製作一個網球比賽項目。我們應該使用txt文件,在那裏他們正在閱讀,我們需要能夠提取一定數量的玩家,這將被用於模擬比賽。從列表中的txt文件中獲取一定數量的行。

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(); 

而在我的主要我加載文件並打印它。這是完美的。但是我需要能夠從列表中僅打印8,16,32或64個玩家。

+2

_players.Take(16)_或_players.Skip(16)。取(16)_等等。參數化16並創建一個返回子集的方法 – Steve

回答

0

有辦法做到這一點。

  1. 聲明一個常數(MAX_PLAYERS)或存儲的要即,8,16,32或64。聲明一個計數器玩家MAX_COUNT和在while循環增加它的變量。一旦計數器達到從循環中退出。在這裏你只會得到你感興趣的第一個8或16個玩家形式的文件。當所有記錄不感興趣時​​,不需要閱讀完整文件。

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

  • 您已經使用該語句players.Shuffle();。所以在洗牌之後從列表中選擇頂部MAX_PLAYERS。當你保留完整的玩家列表以及所選擇的列表時,這更加合乎邏輯。
  • var selectedList = players.Take(MAX_PLAYERS);

    +0

    Worked awesome!謝謝:D – Catchybatchy

    +0

    @Catchybatchy,如果有效,請將其標記爲答案。 –

    0

    你可以改變你的ToString()方法接收兩個參數
    第一個是你想要的字符串中返回球員的數量,第二個參數是玩家數量在獲得下一批玩家之前從列表中跳過。

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

    添加也是一個屬性,它告訴你有多少玩家在列表

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

    這樣你可以調用一個循環內的ToString,直到你達到總數收到的玩家批次球員不是改變你只需添加自己的方法的ToString()方法返回的球員批次的覆蓋出現在列表

    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 
    } 
    

    當然,你喜歡的方式和(例如)返回你的球員的子列表。

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

    可以使用什麼作爲"Reservoir sampling"從未知長度的序列中選擇項目的指定數量(但必須足夠長,提供的所有項目)。

    該算法看起來像這樣:

    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; 
    } 
    

    注意,所得到的數組是按隨機順序;它不包含它們出現在輸入序列中的順序的元素。

    可以用它在從文本文件中隨機(並以隨機的順序)來選擇N行如下:

    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(); 
    
    相關問題