2012-04-04 68 views
3

我已经搜索过,但还没有找到我的答案。免责声明:我是C#的新手,但我有一项工作要创建以下程序:从现有日志文件读取,按Tab分析它们,将结果限制为特定状态(Process E-mail),按分组分组即投资银行),然后按部门计算电子邮件转换量的统计数据,并打印到新的日志文件中。按分组计算后的分组结果

希望在提问之前给出一点关于程序本身的背景知识。我目前正处于我想按部门分组,并且不知道如何去做的地步。

编辑:原始数据:

Status   Division  Time   Run Time Zip Files Conversions Returned Files Total E-Mails 
Process E-mail Investment Bank 12:00 AM 42.8596599 1    0    1    1 
End Processing     12:05 AM 44.0945784 0    0    0    0 
Process E-mail Investment Bank 12:10 AM 42.7193253 2    1    0    1 
Process E-mail Treasury   12:15 AM 4.6563394 1    0    2    2 

这里是我到这一点代码:

static void Main() 
{ 
    { 

     List<string> list = new List<string>(); 
     using (StreamReader reader = new StreamReader(Settings.LogPath + "2012-3-10.log")) 
     { 
      string line; 
      int i = 0; 
      while ((line = reader.ReadLine()) != null) 
      { 
       list.Add(line); 
       i++; 

       string[] split = line.Split('\t'); 

       string processing = split[0]; 

        if(processing.StartsWith("Process")) 
        { 
         string division = split[1]; 
         int zipFiles; 
         int.TryParse(split[4], out zipFiles); 
         int conversions; 
         int.TryParse(split[5], out conversions); 
         int returnedFiles; 
         int.TryParse(split[5], out returnedFiles); 
         int totalEmails; 
         int.TryParse(split[5], out totalEmails); 

所以我有计划的地步,它会吐出的东西这样的控制台:

Investment Bank 
1 
0 
1 
1 

Treasury 
1 
0 
2 
2 

Investment Bank 
2 
1 
0 
1 

我现在想要做的,是由“投资银行”,“财政部”,等组c然后能够计算总数。

最后的日志文件看起来像这样:

Division   Zip Files Conversions Returned Files Total E-mails 
Investment Bank 3   1    1    2 
Treasury   1   0    2    2 
+0

什么是您的原始数据? – 2012-04-04 13:57:22

+0

为什么不只是在流读取器上使用开关盒来根据您的标准分离数据(无论是指定Treasury vs. Investment Bank等)。我个人可能会捕获每个部门作为自己的对象,并将其包装在父对象中以供引用。 IE Class Division有一个名单和List CBRRacer 2012-04-04 14:18:46

+0

@Johnny_D - 添加了原始数据集,介意你这只是一个非常小的日志文件视图,还有更多的部门等 – 2012-04-04 14:27:16

回答

1

下面的代码做你所需要的:

string filename = @"D:\myfile.log"; 
var statistics = File.ReadLines(filename) 
    .Where(line => line.StartsWith("Process")) 
    .Select(line => line.Split('\t')) 
    .GroupBy(items => items[1]) 
    .Select(g => 
      new 
       { 
        Division = g.Key, 
        ZipFiles = g.Sum(i => Int32.Parse(i[2])), 
        Conversions = g.Sum(i => Int32.Parse(i[3])), 
        ReturnedFiles = g.Sum(i => Int32.Parse(i[4])), 
        TotalEmails = g.Sum(i => Int32.Parse(i[5])) 
       }); 

Console.Out.WriteLine("Division\tZip Files\tConversions\tReturned Files\tTotal E-mails"); 
statistics 
    .ToList() 
    .ForEach(d => Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", 
      d.Division, 
      d.ZipFiles, 
      d.Conversions, 
      d.ReturnedFiles, 
      d.TotalEmails)); 

这可能是更短(虽然不太清楚),如果不能乱用匿名类,但使用数组来代替。让我知道你是否对这样的代码感兴趣。

+0

非常感谢你,这完全是我在找的东西。现在要了解它的逻辑,并试图理解它背后的逻辑;) – 2012-04-04 14:41:46

+0

不,这很好,就像我早些时候说的那样,我的老板只是把我扔在这个项目上,所以我正在学习C#和学习编程。 。 – 2012-04-04 14:47:44

+0

我已经使用了C#(尽管没有那么多LINQ)现在已经有一段时间了。我不知道GroupBy可以如此强大地使用。这是权力的一个很好的例子。 – 2012-04-04 15:38:10

0

我将建立一个类然后处理此。

public class xxxx 
{ 
    Public string Division {get;set} 
    Public Dictionary<string,int> something{get;set;} 
} 

然后你可以只封装他们

List<xxx> Divisions; 

不知道这是否是最佳的,但它的工作。

+0

谢谢你的回复,让我再看看这个......再一次,我对C#非常陌生,所以我不得不做一些研究如何完成这件事。你可以提供一个使用我的数据而不是xxx和某些东西等的例子吗?这将非常有帮助。谢谢! – 2012-04-04 14:30:05