给IEnumerable添加以前的值我有一个数字列表:varseq=newList{1,3,12,19,33};我想将其转换为Convertedtoanewsequence,其中将数字添加到先前的数字以创建新序列:{1,3,12,19,33}-->{1,4,16,35,68我想出了以下内容,但我不喜欢状态变量“计数”。我也不喜欢我在没有任何操作的情况下使用值Enumerable的事实。整数计数=1;varsummed=values.Select(_=>values.Take(count++).Sum());这怎么可能?这是函数式编程中的常见模式,在F#中称为扫描。它类似于C#的Enumerable.Aggregate和F#的折叠,只是它会产生累加器的中间结果以及最终结果。我们可以使用扩展方法在C#中很好地实现扫描:publicstaticIEnumerableScan(thisIEnumerableinput,Funcnext,Ustate){yieldreturnstate;foreach(varitemininput){state=next(state,item);屈服返回状态;}}然后使用如下:varseq=newList{1,3,12,19,33};vartransformed=seq.Scan(((state,item)=>state+item),0).Skip(1);“纯”LINQ:varresult=seq.Select((a,i)=>seq.Take(i+1).Sum());“纯”LINQO(n):varres=Enumerable.Range(0,seq.Count).Select(a=>a==0?seq[a]:seq[a]+=seq[a-1]);也是一个LINQ,状态维护:vartmp=0;varresult=les.Select(a=>{tmp+=a;returntmp;});varseq=新列表{1,3,12,19,33};varsummed=newList();seq.ForEach(i=>summed.Add(i+summed.LastOrDefault()));要使用Linq,仅在使用自定义聚合器后迭代列表:classAggregator{publicListList{get;放;}publicintSum{得到;放;}}..varseq=新列表{1,3,12,19,33};varaggregator=newAggregator{List=newList(),Sum=0};varaggregatorResult=seq.Aggregate(聚合器,(a,number)=>{a.Sum+=number;a.List.Add(a.Sum);returna;});varresult=aggregatorResult.List;varseq=新列表{1,3,12,19,33};for(inti=1;i只是为了提供另一种选择,虽然不是LINQ,但你可以编写一个基于yield的函数来进行聚合:publicstaticIEnumerableSumSoFar(thisIEnumerablevalues){intsumSoFar=0;foreach(intvalueinvalues){sumSoFar+=value;yieldreturnsumSoFar;}}和BrokenGlass一样,这只会对数据进行一次传递,尽管与他的返回不同,迭代器不是列表(令人讨厌的是,你不能轻易地对数字进行通用在列表中键入。)StephenSwensen的回答很好,扫描正是您所需要的。虽然不需要种子,但还有另一个版本的扫描,它更适合您的确切问题。此版本要求您的输出元素类型为与您的输入元素类型(在您的情况下)相同,并且具有不需要传入0然后跳过第一个(0)结果的优点。你可以在C#中实现这个版本的扫描,如下所示:publicstaticIEnumerableScan(thisIEnumerableInput,FuncAccumulator){Tstate=enumerator.Current;屈服返回状态;while(enumerator.MoveNext()){state=Accumulator(state,enumerator.Current);屈服返回状态;}}}然后使用方法如下:以上是C#学习教程:IEnumerable加上前面的值,分享所有内容。如果对你有用,需要了解更多C#学习教程,希望大家多多关注—IEnumerableseq=newList{1,3,12,19,33};IEnumerabletransformed=seq.Scan((state,item)=>state+item);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
