Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Linq对日志文件的行进行分组_Linq - Fatal编程技术网

使用Linq对日志文件的行进行分组

使用Linq对日志文件的行进行分组,linq,Linq,我有一个日志文件中的字符串数组,格式如下: var lines = new [] { "--------", "TimeStamp: 12:45", "Message: Message #1", "--------", "--------", "TimeStamp: 12:54", "Message: Message #2", "--------", "--------", "Message: Message #3"

我有一个日志文件中的字符串数组,格式如下:

var lines = new []
{
    "--------",
    "TimeStamp: 12:45",
    "Message: Message #1",
    "--------",
    "--------",
    "TimeStamp: 12:54",
    "Message: Message #2",
    "--------",
    "--------",
    "Message: Message #3",
    "TimeStamp: 12:55",
    "--------"
}
我想使用LINQ将由----分隔的每组行分组到一个列表中。基本上,我想要一个列表或类似的列表,其中每个内部列表包含4个字符串-2个分隔符、一个时间戳和一条消息

我应该补充一点,我希望尽可能使其通用,因为日志文件格式可能会改变

可以这样做吗?

这样行吗

var result = Enumerable.Range(0, lines.Length / 4)
                       .Select(l => lines.Skip(l * 4).Take(4).ToList())
                       .ToList()
编辑:

这看起来有点粗糙,但我相信它可以清理干净

    IEnumerable<List<String>> GetLogGroups(string[] lines)
    {
        var list = new List<String>();
        foreach (var line in lines)
        {
            list.Add(line);
            if (list.Count(l => l.All(c => c == '-')) == 2)
            {
                yield return list;
                list = new List<string>();
            }
        }
    }

假设您的结构始终是

delimeter
TimeStamp
Message
delimeter

public List<List<String>> ConvertLog(String[] log)
{
    var LogSet = new List<List<String>>();
    for(i = 0; i < log.Length(); i += 4)
    {
        if (log.Length <= i+3)
        {
           var set = new List<String>() { log[i], log[i+1], log[i+2], log[i+3] };
           LogSet.Add(set);
        }
    }

}
还是在林克

public List<List<String> ConvertLog(String[] log)
{
   return Enumerable.Range(0, lines.Length / 4)
                    .Select(l => lines.Skip(l * 4).Take(4).ToList())
                    .ToList()

}

实际上,您应该能够比返回列表>做得更好。如果您使用的是C4,则可以将每组值投影到一个动态类型中,其中冒号前的字符串成为属性名,值位于左侧。然后创建一个自定义迭代器,该迭代器读取这些行,直到每个集合中出现结尾,然后返回该行。在MoveNext上,阅读下一组行。冲洗并重复,直到EOF。我现在没有时间写一个完整的实现,但是我在CSV中阅读和在动态对象上使用LINQ的示例可能会让您了解您可以做什么。看见注意:这个示例是用VB编写的,但同样的操作也可以用C编写,只需做一些修改


迭代器实现还有一个额外的好处,即在解析之前不必将整个文档加载到内存中。使用此版本,一次只能加载一组块的数量。它允许您处理非常大的文件。

Ah-自定义迭代器听起来很完美。我会尝试一下。我添加了一条注释,说我希望解决方案尽可能通用,但谢谢。@RB我添加了另一个代码段;看看这是否有帮助。根据你的编辑,我接受这个答案。非常感谢: