使用LINQ在标记元素处拆分列表?

McK*_*eG1 3 .net linq list

我有一个List<T>'常规'元素和'标记'元素的混合物.我想把它分成一个List<List<T>>,打破标记.

例如,给定{a,b,M,c,d,e,f,M,g}的输入,其中'M'是标记元素,我想得到{{a,b},{c,d, e,f},{g}}

使用循环很容易完成这项工作,但似乎应该可以用LINQ更紧凑地表达它,并且经过一些头痛之后,我就看不出如何.(我觉得LINQ-fu不够.)

Kei*_*thS 5

嗯...

varSplitList = myList.Aggregate(new List<List<T>>{new List<T>()}, 
   (sl,t)=> {
      if(/*T is a marker element*/) sl.Add(new List<T>());
      else sl.Last().Add(t); 
      return sl;
   });
Run Code Online (Sandbox Code Playgroud)

可能有一种更易读的方式,但这应该有效.Aggregate是一种非常强大的"系列计算"方法,可用于这些类型的事情.您为它提供了一个"种子"(在这种情况下是一个带有单个子列表的新列表列表),并且对于源中的每个元素,执行操作,该操作接受种子和当前元素并返回(可能已修改) seed,然后传递给下一个元素的操作.

作为一个更简单的例子,这是Linq中的Factorial计算器:

long fact = Enumerable.Range(1,n).Aggregate(1, (f,n)=>f*n));

Enumerable.Range()产生一个从1到n的整数范围.Aggregate函数以1开头,对于每个元素,将种子乘以元素:

1*1 = 1 1*2 = 2 2*3 = 6 6*4 = 24 24*5 = 120 ...

最后,fact在执行所有计算之后给出种子的值.

  • 我会给你风格点(和一个upvote),但我会说这显然不比等效的循环实现更紧凑 - 它几乎只是LINQ服装的循环. (2认同)