使用 linq 在 c# 中将每一行作为组

Take each lines as group in c# using linq

我有一个包含 1000 行的字符串数组,如何使用 linq c# 提取每 25 行并将它们分组为一个文本。 我可以使用循环,但我需要使用 linq 的代码。

var blocks = File.ReadLines(filename)
                    .Select((s, i) => new { s, i })
                    .GroupBy(x => x.i / 25)
                    .Select(g => String.Join(" ", g.Select(x => x.s)))
                    .ToList();

也可以使用Morelinq的Batch方法:https://code.google.com/p/morelinq/source/browse/MoreLinq/Batch.cs

因为您在问题中标记了 take,下面介绍了如何使用 Linq 中的 Take() 获得与 @EZI 相同的结果。

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        List<string> _1000Lines = new List<string>();
        for (int i = 1; i <= 1000; i++)
            _1000Lines.Add(i.ToString());

        for (int i = 0; i < _1000Lines.Count; i += 25) 
        {
            // Use Skip() to skip the previous 25 items from the previous iteration
            Console.WriteLine(String.Join(" ", _1000Lines.Skip(i).Take(25)));
        }
    }
}

Fiddle Demo

当问题是关于一个简单的 linq 时,我认为答案应该是 好看 和性能。所以,我准备了一个测试用例。

由于这是一个社区 wiki,请随时更新它..

var arr = Enumerable.Range(0, 20000).Select(x => x.ToString()).ToArray();

var t1 = Measure(() =>
{
    var blocks = arr
                .Select((s, i) => new { s, i })
                .GroupBy(x => x.i / 25)
                .Select(g => String.Join(" ", g.Select(x => x.s)))
                .ToList();
}, 1000);


var t2 = Measure(() =>
{
    var allLines = new List<string>();
    for (int i = 0; i < arr.Length; i += 25)
    {
        allLines.Add(String.Join(" ", arr.Skip(i).Take(25)));
    }

}, 1000);


var t3 = Measure(() =>
{
    int count = 0;
    var blocks = arr
                .GroupBy(x => count++ / 25)
                .Select(g => String.Join(" ", g))
                .ToList();
}, 1000);


var t4 = Measure(() =>
{
    var blocks = arr.Batch(25, x => x)
                .Select(g => String.Join(" ", g))
                .ToList();
}, 1000);


Console.WriteLine("EZI: {0}\nShar1er80: {1}\nModified-EZI: {2}\nMoreLinq'sBatch: {3}", t1,t2,t3,t4);

long Measure(Action action, int n)
{
    action();
    var sw = Stopwatch.StartNew();
    for (int i = 0; i < n; i++)
    {
        action();
    }
    return sw.ElapsedMilliseconds;
}

输出:

EZI: 3548
Shar1er80: 24362
Modified-EZI: 1782
MoreLinq'sBatch: 1300