【问题标题】:Get an certain number of lines from a txt file in a list.从列表中的 txt 文件中获取一定数量的行。
【发布时间】:2017-09-24 22:19:26
【问题描述】:

我有问题。我正在为一个学校项目制作网球锦标赛计划。我们应该使用 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();

在我的 main 中,我加载文件并打印它。这完美无缺。但我只需要能够从列表中打印 8、16、32 或 64 名玩家。

【问题讨论】:

  • players.Take(16)players.Skip(16).Take(16) 等等。将 16 参数化并创建一个返回子集的方法

标签: c# text-files readline readlines


【解决方案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();

【讨论】:

    【解决方案2】:

    有办法做到这一点。

    1. 声明一个常量(MAX_PLAYERS)或一个变量来存储您想要的玩家的 Max_Count,即 8、16、32 或 64。声明一个计数器并在 while 循环中递增它。一旦达到计数器退出循环。在这里您只会得到您感兴趣的第一个 8 或 16 个玩家表格文件。当所有记录不感兴趣时​​,不需要阅读完整文件。

    while (!par.EndOfData &amp;&amp; counter &lt; MAX_PLAYERS)

    1. 您使用了语句players.Shuffle();。因此,只需在洗牌后从列表中选择顶部的MAX_PLAYERS。这样更合乎逻辑,因为您保留了完整的球员名单以及从中选出的名单。

    var selectedList = players.Take(MAX_PLAYERS);

    【讨论】:

    • 工作太棒了!谢谢:D
    • @Catchybatchy,如果有效,请将其标记为答案。
    【解决方案3】:

    您可以更改 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 并接收批量玩家,直到达到列表中存在的玩家总数

    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
    }
    

    当然,无需更改 ToString() 方法的覆盖,您只需添加自己的方法,以您喜欢的方式批量返回玩家,并(例如)返回玩家的子列表。

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

    【讨论】:

      猜你喜欢
      • 2020-02-29
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      相关资源
      最近更新 更多