通过本质上用“自身”来压缩序列,通过将原来IEnumerable的起始位置偏移1来生成Zip序列。因此,给定.Net4.0中的Zip扩展,假设一个点类型为Point,以及一个合理的距离公式,您可以像这样进行调用以生成从一个点到下一个点的一系列距离,然后对距离求和:vardistances=points.Zip(points.Skip(1),Distance);双totalDistance=distances.Sum();面积和质心计算的相似之处在于它们需要迭代序列,处理每对点(points[i]和points[i]i+1])。我想做一个通用的IEnumerable扩展,适用于实现这些(可能还有其他)对序列进行操作的算法,一次取两个项目(点[0]和点[1],点[1]和点[2],...,points[n-1]和points[n](或n-2和n-1...)并应用该函数。我的通用迭代器将具有与Zip类似的签名,但不会接收第二个序列进行压缩,因为它实际上只是压缩自己。我的第一次尝试是这样的:}开始编辑:看到响应后,我实现了Pairwise并显式使用了底层枚举器,如下所示:publicstaticIEnumerablePairwise(thisIEnumerableseq,FuncresultSelector){使用(IEnumeratore=seq.GetEnumerator()){如果(e.MoveNext())prev=e.Current;while(e.MoveNext())yieldreturnresultSelector(prev,prev=e.Current);}}虽然肯定比我的初始版本更复杂,但这个迭代输入序列是一次,原始迭代两次。EndEdit使用我的通用迭代器,我可以编写如下函数:publicstaticdoubleLength(thisIEnumerablepoints){returnpoints.ZipMyself(Distance).Sum();}并调用它:doubled=points.Length();和doubleGreensTheorem(Pointp1,Pointp1){returnp1.X*p2.Y-p1.Y*p2.X;}publicstaticdoubleSignedArea(thisIEnumerablepoints){returnpoints.ZipMyself(GreensTheorem)。Sum()/2.0}publicstaticdoubleArea(thisIEnumerablepoints){returnMath.Abs??(points.SignedArea());}publicstaticboolIsClockwise(thisIEnumerablepoints){returnSignedArea(points)<0;}并调用它们是:doublea=points.Area();boolisClockwise=points.IsClockwise();在这种情况下,是否有任何理由不根据Zip和Skip(1)实施“ZipMyself”?LINQ中是否已经有一些自动化的东西(自己压缩列表)-并不是说??它需要更容易制作;-)此外,是否有更好的扩展名可以反映它是一个众所周知的模式(如果它确实如此)是一个众所周知的模式)?这是一个关于面积计算的StackOverflow问题的链接。这是问题2432428。还有一个指向关于Centroid的维基百科文章的链接。如果有兴趣,请访问维基百科并搜索Centroid。刚开始,所以没有足够的代表发布多个链接。开始编辑为了完整起见,如果有人在搜索距离、面积或质心后到达这里,这是我的函数,它获取位置类型列表(假设面积和质心关闭)并返回距离(沿)、面积和质心.当前位置:publicstructPosition{publicdoubleX;公共双Y;staticpublicdoubleDistance(Positionp1,Positionp2){doubledx=p2.X-p1.X;双dy=p2.Y-p1.Y;返回Math.Sqrt(dx*dx+dy*dy);}}publicstaticclassPointMath{publicstaticdoubleDistance(IEnumerablepts){returnpts.Pairwise((p1,p2)=>Position.Distance(p1,p2)).Sum();}privatestaticboolIsClockwise(IEnumerablepts){returnSignedArea(pts)<0;}privatestaticdoubleSignedArea(IEnumerablepts){returnpts.Pairwise((p1,p2)=>(p1.X*p2.Y-p1.Y*p2.X)).Sum()/2.0;}publicstaticdoubleArea(IEnumerablepts){returnMath.Abs??(SignedArea(pts));}publicstaticPositionCentroid(IEnumerablepts){doublea=SignedArea(pts);varc=pts.Pairwise((p1,p2)=>new{x=(p1.X+p2.X)*(p1.X*p2.Y-p2.X*p1.Y),y=(p1.Y+p2.Y)*(p1.X*p2.Y-p2.X*p1.Y)}).Aggregate((t1,t2)=>new{x=t1.x+t2.x,y=t1.y+t2.y});返回新的位置(1.0/(a*6.0)*cx,1.0/(a*6.0)*cy);随意评论结束编辑此外,是否有更好的扩展名可以反映它是一个众所周知的模式(如果它确实是一个众所周知的模式)?是的-它也称为Pairwise。以前做过,例如这里。在此之前有一个问题。正如您所指出的,Pairwise现在可用于.NET4.0的Zip。对于LINQtoObjects解决方案来说,这似乎是一种合理的方法,尽管在.NETv3.5上运行的版本可能对更广泛的受众更有用。当我做类似的事情时,我称之为SelectWithPrevious并且有一个版本重载了“SelectWithPreviousItem”(采用Func)和“SelectWithPreviousResult”(采用Func)。此外,我通过直接存储最后一个元素而不是像Zip方法那样将序列迭代两次来让它工作。从未使用过LINQ-to-SQL,我不能肯定地说,但我想知道Zip/Skip方法是否两次访问服务器以评估查询两次。以上就是C#学习教程:如何自己压缩一个IEnumerable共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处:
