如何将列表写入文本文件.每行写50个项目 [英] How to write a list to a text file. Write 50 items per line

查看:63
本文介绍了如何将列表写入文本文件.每行写50个项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个程序,该程序从文件读取数据,将数据存储在列表中,然后将数据以特殊格式写入新文件.我已经创建了读取原始文件并将其存储在列表中的方法.

I am working on a program where I read data from a file, store that data in a list and write that data to a new file in a special format. I have created the method to read the original file and store it in a list.

我从中读取的文件是数字列表.每行一个数字.

The file I read from is a list of numbers. One number per line.

写入新文件的方法出现问题.我在处理50项并将它们写入一行,然后在接下来的50项并写入下一行时遇到问题.该方法是获取前50个项目并将其写入,并在每行上重复前50个项目.我知道这是因为我的第二个for循环.只是不确定如何解决.任何帮助,将不胜感激.下面是我的代码:

I'm having issue with my method that writes to the new file. I'm having an issue with taking 50 items and writing them to a line and then taking the next 50 items and writing on the next line. The method is taking the first 50 items and writing them and repeating those 50 items on each line. I know this is because of my second for loop. Just not sure how to fix. any help would be appreciated. Below is my code:

public static void WriteFormattedTextToNewFile(List<string> groupedStrings)
{
    string file = @"C:\Users\e011691\Desktop\New folder\formatted.txt";
    StreamWriter sw = new StreamWriter(file, true);

    for (int i = 0; i < ReadFile.GroupedStrings.Count; i++)
    {
        sw.Write($"{DateTime.Now:yyyy MM dd  hh:mm:ss}\t\t");

        for (int j = 0; j < 50; j++)
        {
            sw.Write($"{ReadFile.GroupedStrings[j]}\t");
        }
        sw.WriteLine();
    }
    sw.Close();
}

推荐答案

我将给您三个选择(和奖励).

I'll give you three options (and a bonus).

第一个选项.使用带有迭代器块的自定义 Chunk(int) linq运算符.诀窍是内部方法使用与外部方法相同的枚举器.似乎很多代码,但是一旦有了 Chunk()方法,就可以在任何地方使用它.还要注意,此选项甚至不需要 List< string> .它将与 any IEnumerable< string> 一起使用,因为我们从不按索引引用任何元素.

First option. Use a custom Chunk(int) linq operator using iterator blocks. The trick is the inner method uses the same enumerator as the outer. Seems like a lot of code, but once you have the Chunk() method, you can use it anywhere. Also note this option doesn't even need a List<string>. It will work with any IEnumerable<string>, since we never reference any elements by index.

public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> values, int chunkSize)
{
    var e = values.GetEnumerator();
    while (e.MoveNext())
    {
        yield return innerChunk(e, chunkSize);
    }
}

private static IEnumerable<T> innerChunk<T>(IEnumerator<T> e, int chunkSize)
{
    //If we're here, MoveNext() was already called once to advance between batches
    // Need to yield the value from that call.
    yield return e.Current;

    //start at 1, not 0, for the first yield above  
    int i = 1; 
    while(i++ < chunkSize && e.MoveNext()) //order of these conditions matters
    {
        yield return e.Current;
    }
}

public static void WriteFormattedTextToNewFile(IEnumerable<string> groupedStrings)
{
    string file = @"C:\Users\e011691\Desktop\New folder\formatted.txt";
    using (var sw = new StreamWriter(file, true))
    {   
        foreach(var strings in groupedStrings.Chunk(50))
        {
            sw.Write($"{DateTime.Now:yyyy MM dd  hh:mm:ss}\t\t");
            foreach(var item in strings)
            {
               sw.Write($"{item}\t");
            }
            sw.WriteLine();
        } 
    }
}

这是基本的概念验证Chunk()确实有效.

作为奖励选项,这是从第一个选项使用 Chunk()方法的另一种方法.请注意,实际方法变得多么小巧而直接,但是长长的全线字符串的构造可能会使这种方法的效率降低.

As a bonus option, here is another way to use the Chunk() method from the first option. Note how small and straight-forward the actual method becomes, but the construction of the long full-line strings likely makes this less efficient.

public static void WriteFormattedTextToNewFile(IEnumerable<string> groupedStrings)
{
    string file = @"C:\Users\e011691\Desktop\New folder\formatted.txt";
    using (var sw = new StreamWriter(file, true))
    {   
        foreach(var strings in groupedStrings.Chunk(50))
        {
            sw.Write($"{DateTime.Now:yyyy MM dd  hh:mm:ss}\t\t");
            sw.WriteLine(string.Join("\t", strings));
        } 
    }
}

第二个选项.使用单独的整数/循环跟踪.注意内部循环的额外条件,仍然使用 i 值而不是 j 来引用当前位置,并在内部循环中递增 i 环形.这称为控制/中断循环.请注意,我们如何能够在每行上写入结束行和初始日期值,以使它们也以正确的顺序出现在代码中:首先是页眉,然后是项目,然后是页脚,而我们无需进行复杂的条件检查

Second option. Keep track using a separate integer/loop. Note the extra condition on the inner loop, still using the i value rather than j to reference the current position, and incrementing i in the inner loop. This is called a Control/Break loop. Note how we are able to write the end line and initial date value on each line such that they also appear in the correct order in the code: first the header, then the items, then the footer, and we do it without complicated conditional checks.

public static void WriteFormattedTextToNewFile(List<string> groupedStrings)
{
    string file = @"C:\Users\e011691\Desktop\New folder\formatted.txt";
    using (var sw = new StreamWriter(file, true))
    {   
        int i = 0;
        while(i < groupedStrings.Count)
        {
           sw.Write($"{DateTime.Now:yyyy MM dd  hh:mm:ss}\t\t");
           for(int j = 0; j < 50 && i < groupedStrings.Count; j++)
           {
              sw.Write($"{groupedStrings[i]}\t");
              i++;
           }
           sw.WriteLine();
        }
    }
}

第三种选择.使用模数运算符()跟踪.这个选项(或在同一循环中使用第二个 j 值的类似选项)是许多人首先转向的地方,但要当心;从表面上看,此选项很难正确解决,尤其是当问题变得更加复杂时.

Third option. Keep track using the modulus operator (%). This option (or a similar option using a second j value in the same loop) is where many would turn first, but beware; this option is deceptively difficult to get right, especially as the problem gets more complicated.

public static void WriteFormattedTextToNewFile(List<string> groupedStrings)
{
    string file = @"C:\Users\e011691\Desktop\New folder\formatted.txt";
    using (var sw = new StreamWriter(file, true))
    {
        for(int i = 0; i < groupedStrings.Count;i++)
        {
            if (i % 50 == 0)
            {
                if (i > 0) sw.WriteLine();
                sw.Write($"{DateTime.Now:yyyy MM dd  hh:mm:ss}\t\t");
            }

            sw.Write($"{groupedStrings[i]}\t");
        }
        sw.WriteLine();
    }
}

这篇关于如何将列表写入文本文件.每行写50个项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆