C#学习教程:通过检查元素的条件将列表拆分为子列表像这样:[1,2,3,0,4,5,0,6,7]=>[[1,2,3,0],[4,5,0],[6,7]]好吧,用两个for循环可以很容易地完成,但我想知道是否可以用LINQ来做到这一点。有这样的问题[1]、[2],但相比之下,它们依赖于列表之外提供的条件。注意:我知道在一篇文章中问多个问题是不礼貌的,但是如果有人熟悉函数式编程(因为从本质上讲,这实际上是一个FP问题),我也想看看他们的观点和这个问题的答案可能的解决方案。您在集合的不同元素之间存在依赖关系,特别是对于您想知道“前一个元素是否为零?”的每个元素。只要您的查询依赖于前一个元素(或者更一般地说,无论何时您的查询依赖于同一序列的其他元素),您都应该得到一个聚合(或更通用的函数式编程术语,fold)。这是因为,与其他LINQ运算符不同,聚合允许您将状态从一个迭代传递到下一个迭代。因此,为了回答您的问题,我将按如下方式在LINQ中编写查询。//假设我们的整数列表称为值varsplitByZero=values.Aggregate(newList>{newList()},(list,value)=>{list.Last().Add(value);if(value==0)list.Add(newList());返回列表;});我将其分解为多个部分,以便更好地解释我的想法。values.Aggregate(newList>{newList()},之前说过,Aggregate是因为我们需要携带state。把一个新的空list放到一个list的list中,去掉了List>的marginalcase,没有列在其中。(list,value)=>{...}再次查看我们的lambda表达式的签名(即Func>,int,List>),我们可以看到显式传递的状态:我们接受一个List>并返回相同的。list.Last().Add(值);因为我们总是想处理最新的列表,所以我们得到了列表的Last()元素(由于上面的部分,它们永远不会为空)。如果(值==0)列表。添加(新列表());这是我们进行拆分的地方——在下一次迭代中,对Last()的调用将返回这个新列表。返回列表;我们最终将状态传递给下一次迭代。这可以很容易地在SplitOn方法中进行概括,如下所示:.Last().Add(value);if(predicate(value))list.Add(newList());returnlist;});由于Enumerables的工作方式,使用IEnumerable而不是List该版本不太清楚,但同样,从上面的代码创建起来并不是特别困难,它看起来像(通过三元运算符进行了简化):publicstaticIEnumerable>SplitOn(thisIEnumerablesource,Funcpredicate){返回源。聚合(Enumerable.Repeat(Enumerable.Empty(),1),(list,value)=>{list.Last().Concat(Enumerable.Repeat(value,1));returnpredicate(value)?list.Concat(Enumerable.Repeat(Enumerable.Empty(),1)):列表;});您可能还会发现Haskell的splitOn实现很有趣,因为它完全符合您的要求。我会称之为非同寻常(轻描淡写)。这是一个有用的方法:publicstaticIEnumerable>MarkWithLabels(thisIEnumerablesrc,PredicatesplittingCondition){intlabel=0;foreach(TIniteminsrc){yieldreturnnewTuple(item,label);if(splittingCondition(item))标签++;}}有了它,下面的作品intbreakingValue=0;varsubseq=seq.MarkWithLabels(i=>i==breakingValue).GroupBy(tup=>tup.Item2).Select(group=>group.Select(tup=>tup.Item1).ToArray()).ToArray();FP解决方案除了foreach可以基本相同。我完全根据Zack的回答编译了两个扩展方法。以上就是C#学习教程:通过检查元素的条件将列表拆分为子列表,共享所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注—publicstaticIEnumerable>SplitBefore(thisIEnumerablesource,Funcpredicate){returnsource.Aggregate(Enumerable.Repeat(newList(),1),(list,value)=>{if(predicate(value))list=list.Concat(Enumerable.Repeat(newList(),1));list.Last().Add(value);返回列表;}).Where(list=>list.Any());}publicstaticIEnumerable>SplitAfter(thisIEnumerablesource,Funcpredicate){returnsource.Aggregate(Enumerable.Repeat(newList(),1),(list,value)=>{list.Last().Add(value);returnpredicate(value)?list.Concat(Enumerable.Repeat(newList(),1)):list;}).Where(list=>list.Any());}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
