从列表中的txt文件中获取一定数量的行。

时间:2017-04-27 08:21:51

标签: c# text-files readline readlines

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

3 个答案:

答案 0 :(得分: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();

答案 1 :(得分:0)

有办法做到这一点。

  1. 声明一个常量(MAX_PLAYERS)或一个变量来存储你想要的玩家的Max_Count,即8,16,32或64.声明一个计数器并在while循环中递增它。一旦到达计数器退出循环。在这里,您将只获得您感兴趣的前8个或16个玩家表格。当所有记录不感兴趣时​​,不需要阅读完整档案。
  2. while (!par.EndOfData && counter < MAX_PLAYERS)

    1. 您使用了players.Shuffle();语句。因此,在洗牌后从列表中选择顶部MAX_PLAYERS。这样更合乎逻辑,因为您保留了完整的玩家列表以及所选择的列表。
    2. var selectedList = players.Take(MAX_PLAYERS);

答案 2 :(得分: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并接收批量玩家,直到达到列表中的玩家总数

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