根据块大小(行数)将List <string>拆分为不同的List

时间:2019-11-03 01:18:09

标签: c# list text-files

让我们说我有一个很大的字符串列表,称为“ lines”,它包含文本文件中的所有行(通常是大约100k-100万行的大数字)

List<string> lines = File.ReadAllLines("Lines.txt");

我的问题是我需要根据用户输入的块大小来分割文件(或列表)。假设我们有1万行 Lines.txt,用户输入4400行的大块

File1 = 4400 Lines 
File2 = 4400 Lines
File3 = 1200 Lines

我尝试使用我的同事推荐的类似方法,但是我不明白,它不起作用。

public static class ListExtensions
{
    public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize) 
    {
        return source
            .Select((x, i) => new { Index = i, Value = x })
            .GroupBy(x => x.Index / chunkSize)
            .Select(x => x.Select(v => v.Value).ToList())
            .ToList();
    }
}

对于我如何解决此问题的任何建议或帮助,我将不胜感激。

4 个答案:

答案 0 :(得分:1)

这个怎么样-

var numOfChunks = lines.Count / chunkSize; // initial number of chunks
if(lines.Count % chunkSize > 0) { numOfChunks++; } // add one chunk for remainder if there is a remainder
for (var i = 0; i <= numOfChunks; i++)
{
     var chunk = lines.Skip(i * chunkSize).Take(chunkSize);
    // Do something with chunk, like writing to file
}

答案 1 :(得分:0)

Linq的TakeSkip在这里可能会有所帮助。

public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize) 
{
    var pages = new List<List<T>>();
    var page = 0;
    while(source.Any()) {
        var l = source.Skip(page++*chunkSize).Take(chunkSize).ToList();
        if(!l.Any()) break;
        pages.Add(l);
    }
    return pages;
}

答案 2 :(得分:0)

这里是没有Linq的版本。

public static List<List<T>> ChunkBy<T>(List<T> source, int chunkSize) 
{
    var pages = new List<List<T>>();
    var page = new List<T>();
    var i = 0;
    foreach( var s in source ) {
        if((i++ % chunkSize) == 0 ) { page = new List<T>(); pages.Add(page);}
        page.Add(s);
    }

    return pages;
}

答案 3 :(得分:0)

这是可用于此任务的一种方法。您需要确保传递要分块的sourceFile文件,将文件写入的destDirectory和块大小。

private static void ChunkFile(string sourceFile, string destDirectory, int chunkSize)
{
    // Read all lines
    var lines = File.ReadLines(sourceFile)

    // Calculate number of chunks needed
    // Round up to get correct chunks
    var numberOfChunks = (int)Math.Ceiling((double)lines.Count() / chunkSize);

    // Go through each chunk and write to file
    for (var i = 0; i < numberOfChunks; i++)
    {
        // Skip lines chunks we've already seen, and take the next chunk
        var chunk = lines.Skip(i * chunkSize).Take(chunkSize);

        // Write chunk to destination path
        File.WriteAllLines(Path.Combine(destDirectory, $"File{i + 1}.txt"), chunk);
    }
}

应该以File1.txt,File2.txt,File3.txt等格式生成分块文件。

您还需要实施错误处理,例如检查sourceFile是否存在等。

另外,我建议从System.Linq看一下这两种LINQ方法:

System.IO看这些IO方法来读取/写入文件也可能会有所帮助:

注意:我们使用File.ReadLines而非File.ReadAllLines来避免将整个文件读入内存。当读取大文件并降低性能时,这是必需的。您可以在What is the difference between File.ReadLines() and File.ReadAllLines()?上了解有关此内容的更多信息。