2014-07-08 77 views
-7

你们是无情的,让像我这样的新程序员感受到真正的欢迎。 :)Groupby Linq C#

好吧让我再试试这一次,如果我能正确解释我的情况。像下面的答案之一,我有一个字符串,其中包含以下信息。这是使用while循环创建的,每行以Environment.Newline结尾(第一行没有错误,实际上有一个空行)。

var s = @" 
ABC-123, 80000, 1400 
ABC-123, 70000, 1250 
ABC-123, 65000, 1200 
BCD-234, 90000, 1300 
BCD-234, 95000, 1100 
XYZ-111, 24000, 1000 
XYZ-111, 24000, 1000" 

我最初问是否有办法按第一列即,所有的ABC-123被分组在一起,第二个被加和并且第三列被平均。请忽略总和和平均值,我只需要先了解如何组合。

此处,我感到困惑,使用下面的语句下面的答案之一:

var ss = s.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries) 
       .Select(x => x.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) 
       .GroupBy(y => y[0]); 

我明白了什么,答案正在试图做的,但我需要帮助写结果返回到一个字符串(也许这不是正确的选择,我不知道,总是接受建议),以便我可以使用StreamWriter将结果保存为csv。

我试着了解IEnumerables,但所有的视频/网站只是混淆了我的地狱。我也试着输出SS的结果,这样也许,如果我有一个视觉表现,那么我可以重写,但是当我这样做,我得到的结果如下:

 Console.WriteLine(ss); 
     Console.Read(); 

System.Linq.GroupedEnumerable 3[<>f__AnonymousType0 1 System.Char],System.Char,<

f__AnonymousType0`1 [System.Char]

输出我希望会是这个样子的字符串。

output = "ABC-123, 215000, 1283 
BCD-234, 185000, 1200 
XYZ-111, 48000, 1000" 
+1

为什么不先拆呢,放在一个表或其他对象? –

+1

什么专栏。这是一个字符串。字符串没有列 – Liam

+1

“输出为”的字符串是什么意思?单个字符串,还是多个字符串?你试过什么了? –

回答

1

假设你的输出是一个字符串数组,一个方法是通过将第一结果拆分用逗号和组串:

list.Select(s => s.Split(',')) 
    .GroupBy(a => a[0]) 

注意,输出将是一个IEnumerable<string[]> - 如果你想原始字符串只要保持在原来的选择:

list.Select(s => new {S = s, Parts = s.Split(',')}) 
    .GroupBy(a => a.Parts[0]) 
    .Select(g => new {Key = g.Key, lines = g.Select(a => a.S) }); 
+0

什么是名单?>> –

+0

很抱歉,如果我错了,但只是好奇这将如何工作。上述文本中的每行代表一行,预期的输出是对整行进行分组。有了这个逻辑,我们将有21个元素而不是7个数组:) –

2

假设所有inputdata是一个长字符串:

var s = @"ABC-123, 80000, 1400 
     ABC-123, 70000, 1250 
     ABC-123, 65000, 1200 
     BCD-234, 90000, 1300 
     BCD-234, 95000, 1100 
     XYZ-111, 24000, 1000 
     XYZ-111, 24000, 1000"; 

var ss = s.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries) //split by newlines 
      .Select(x => x.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) //Split each line by , 
      .GroupBy(y => y[0]); //group by first element of array 

如果它是一个字符串数组已经,您可以忽略换行符

编辑的第一次分裂:嗯,我们无法解释背后的IEnumerable,LINQ理论和这里分组。有很多优秀的教程。也许你应该先学习一些基础知识,然后再跳进这些东西。

但对于您的特定问题,这应该这样做:

var lines = ss.Select(z => new {cKey = z.Key, 
          c2sum = z.Select(a=> Convert.ToInt32(a[1])).Sum(), 
          c3avg = z.Select(a=> Convert.ToInt32(a[2])).Average()}); 
foreach (var l in lines) 
    Console.WriteLine("{0}, {1}, {2}", l.cKey, l.c2sum, l.c3avg); //or whatever stream you want to write to 
+0

当你这样做时,输出生成System.Linq.GroupedEnumerable'3 [System.String [],System.String,System.String []] – user3813607

+0

Yes它当然这样做。你不能只使用'ss.ToString()'或'Console.WriteLine(ss)'。按照您的要求,这只是“按第一列分组”。你必须进一步处理结果。但是,由于您没有告诉我们您期望的结果,我们无法做到这一点。 – derpirscher

+0

对不清楚的说明,你会如何输出这个可读文本(最终,我需要这个写入一个CSV文件)?我尝试使用foreach循环,但我不认为我正朝着正确的方向前进。 – user3813607