当前位置: 首页 > news >正文

邯郸市搞网站服务务的吗无锡网站制作优化

邯郸市搞网站服务务的吗,无锡网站制作优化,唐山如何做百度的网站建设,长春建站公众号概要 本文在前两篇Take源码分析的基础上,着重分析Range参数中有倒数的情况,即分析TakeRangeFromEndIterator的源码实现。 源码及分析 TakeRangeFromEndIterator方法用于处理Range中的开始和结束索引存在倒数的情况。该方法位于Take.cs文件中。通过yie…

概要

本文在前两篇Take源码分析的基础上,着重分析Range参数中有倒数的情况,即分析TakeRangeFromEndIterator的源码实现。

源码及分析

TakeRangeFromEndIterator方法用于处理Range中的开始和结束索引存在倒数的情况。该方法位于Take.cs文件中。通过yield return/break的方式管理迭代过程。

TakeRangeFromEndIterator方法从整体上分为两部分,一部分是TryGetNonEnumeratedCount为真的情况,即souce实现了ICollection接口的情况;另一部分是souce没有实现ICollection接口,TryGetNonEnumeratedCount返回为False的情况。

 private static IEnumerable<TSource> TakeRangeFromEndIterator<TSource>(IEnumerable<TSource> source, bool isStartIndexFromEnd, int startIndex, bool isEndIndexFromEnd, int endIndex)
{if (source.TryGetNonEnumeratedCount(out int count)){startIndex = CalculateStartIndex(isStartIndexFromEnd, startIndex, count);endIndex = CalculateEndIndex(isEndIndexFromEnd, endIndex, count);if (startIndex < endIndex){foreach (TSource element in TakeRangeIterator(source, startIndex, endIndex)){yield return element;}}yield break;}static int CalculateStartIndex(bool isStartIndexFromEnd, int startIndex, int count) =>Math.Max(0, isStartIndexFromEnd ? count - startIndex : startIndex);static int CalculateEndIndex(bool isEndIndexFromEnd, int endIndex, int count) =>Math.Min(count, isEndIndexFromEnd ? count - endIndex : endIndex);
}
  1. 该函数有4个参数,开始索引是否倒数,开始索引值,结束索引是否为倒数,结束索引值;
  2. 如果source实现了ICollection接口,可以在不遍历souce序列的情况下,直接获取序列长度,则TryGetNonEnumeratedCount返回为True;
  3. 调用CalculateStartIndex和CalculateEndIndex内联方法,获取正数的索引值,假设Range是 ^3… ^1,元素共10个,则转换完成后是7…9,即从第7个取到第9个;
  4. 在开始索引值小于结束索引值的前提下,调TakeRangeIterator方法,按照普通正数Range的方法进行处理,并将结果以状态机的形式按照yield return/break方式返回。具体详见 C# Linq源码分析之Take (二)

注意在TryGetNonEnumeratedCount返回为True的情况下,因为可以直接取到序列的元素个数,不需要进行逐个迭代和累加。因此才可以将倒数的Range转换成正数的Range。对于无法获取序列元素的情况,我们看下面的代码分析。

在开始索引是倒数的情况下,进行如下处理,此时假设我们有如下序列,我们的Range是 ^3 … ^1,但是不知道序列内元素个数。
在这里插入图片描述

 Queue<TSource> queue;if (isStartIndexFromEnd){// TakeLast compat: enumerator should be disposed before yielding the first element.using (IEnumerator<TSource> e = source.GetEnumerator()){if (!e.MoveNext()){yield break;}queue = new Queue<TSource>();queue.Enqueue(e.Current);count = 1;while (e.MoveNext()){if (count < startIndex){queue.Enqueue(e.Current);++count;}else{do{queue.Dequeue();queue.Enqueue(e.Current);checked { ++count; }} while (e.MoveNext());break;}}Debug.Assert(queue.Count == Math.Min(count, startIndex));}startIndex = CalculateStartIndex(isStartIndexFromEnd: true, startIndex, count);endIndex = CalculateEndIndex(isEndIndexFromEnd, endIndex, count);Debug.Assert(endIndex - startIndex <= queue.Count);for (int rangeIndex = startIndex; rangeIndex < endIndex; rangeIndex++){yield return queue.Dequeue();}}
  1. 获取souce的迭代器e;
  2. 如果取一个元素失败,证明Range中指定的范围在实际序列中根本取不到,则通过yield break关闭状态机;
  3. 定义缓冲队列queue,将“A”放入队列,元素个数初始值设置为1;
  4. 迭代开始,count < startIndex在元素个数累加器小于启始索引的情况下,每次队列增加一个元素,直到count等于3,此时队列元素是"A", “B”, “C”;
  5. 然后每次删除队首元素,再添加新的元素到队尾,当遍历完整个source序列后,队列元素是“G”, “H”, “I”,此种方法遍历,算法只需要启始索引值,结束索引值完全忽略;
  6. 根据迭代中获取的元素个数count,计算出正数的开始和结束索引,本例应该是6…8;
  7. 将缓冲队列queue按照状态机的形式,通过yield return方式返回;因为rangeIndex < endIndex;,所以最后的返回值是“G”, “H”没有“I”,只会取到结束索引对应元素的前一个元素。

在开始索引不是倒数的情况下, 进行如下处理,此时假设我们有如下序列,我们的Range是 3 … ^2,此时我们并不清楚集合内元素的个数。

请注意在现有的情况下,如果开始索引是正数,结尾索引一定是倒数的。如果结尾索引是正数,更加之前的代码分析,只会进入C# Linq源码分析之Take (二)所介绍的TakeRangeIterator方法。

假设我们使用的数据如下:

在这里插入图片描述

 else{Debug.Assert(!isStartIndexFromEnd && isEndIndexFromEnd);// SkipLast compat: the enumerator should be disposed at the end of the enumeration.using IEnumerator<TSource> e = source.GetEnumerator();count = 0;while (count < startIndex && e.MoveNext()){++count;}if (count == startIndex){queue = new Queue<TSource>();while (e.MoveNext()){if (queue.Count == endIndex){do{queue.Enqueue(e.Current);yield return queue.Dequeue();} while (e.MoveNext());break;}else{queue.Enqueue(e.Current);}}}}
  1. 定义迭代器e 和 集合内初始元素个数计数器设置为0;
  2. 在初始化操作后,count是3,迭代器指向元素C;
  3. 如果count等于 startIndex,证明Range中的取值在下面的序列中可以取到。如果不等,则返回空;
    在这里插入图片描述
  4. 因为是倒数第2个,所以endIndex的数值是2,
  5. D和E进入缓冲队列;
  6. 因为缓冲队列中的长度必须和endIndex相等,队列每进入一个元素到队尾,然后删除队首元素并按照yield return的状态机方式返回。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    最后将所有需要的元素返回。上面算法并不需要直到序列内元素的个数。
http://www.hkea.cn/news/471571/

相关文章:

  • 网站制作先学什么百度新闻下载安装
  • 河南省网站建设哪家好免费观看行情软件网站进入
  • 粘合剂东莞网站建设体育热点新闻
  • 百度网站排名关键词整站优化培训网站建设
  • 网络平台代理seo外包 杭州
  • 东方头条网站源码免费推广软件工具
  • 北京网站建设公司分享网站改版注意事项流程优化四个方法
  • 案例学 网页设计与网站建设手机百度seo快速排名
  • 江门网站建设总部电话产品推广渠道有哪些
  • 网站建设全攻略站长之家ping检测
  • 导航网站 cmsgoogle chrome谷歌浏览器
  • wordpress看其他人博客优化师是做什么的
  • 现在哪个网站还做白拿2021小说排行榜百度风云榜
  • 网站流量seo提升seo排名的方法
  • 做html网站模板下载地址网站页面布局和样式设计
  • 公司网站邮箱费用磁力宅在线搜种子
  • wordpress 缺少临时文件夹刷关键词优化排名
  • 做网站要有什么团队淘宝关键词排名查询工具
  • 开源门户网站源码宁波谷歌seo
  • wordpress+一页一屏seo关键技术有哪些
  • 学校校园网站建设实施方案精准营销的案例
  • 腾讯云服务器可以做网站可以推广发广告的app
  • seo外链友情链接网站运营推广选择乐云seo
  • 做网站 要学 什么语言网站优化公司
  • 天乐测绘网做网站吗搜索引擎广告图片
  • 湖南营销型网站建设多少钱百度关键词优化软件网站
  • 怎样给网站做关键词优化百度词条
  • 做网站哪个平台搭建网站需要什么技术
  • 做gif图的网站简述网络营销的主要方法
  • 做图网站被告seo视频网页入口网站推广