C# 如何使用LINQ实现IList从指定索引开始循环往复迭代
实现方案
我们可以通过给IList<T>写LINQ风格的扩展方法实现需求,核心逻辑利用取模运算自动处理循环重置,同时支持指定起始索引:
方案1:指定获取数量的一次性迭代实现
using System; using System.Collections.Generic; using System.Linq; public static class EnumerableExtensions { /// <summary> /// 从指定索引开始循环遍历IList,返回指定数量的元素 /// </summary> /// <param name="source">目标IList集合</param> /// <param name="startIndex">0基起始索引,若使用1基计数需自行减1</param> /// <param name="takeCount">需要返回的元素总数</param> public static IEnumerable<T> CircularTake<T>(this IList<T> source, int startIndex, int takeCount) { // 参数校验 if (source == null) throw new ArgumentNullException(nameof(source)); if (source.Count == 0) throw new ArgumentException("集合不能为空", nameof(source)); if (startIndex < 0 || startIndex >= source.Count) throw new ArgumentOutOfRangeException(nameof(startIndex), "起始索引超出集合范围"); if (takeCount < 0) throw new ArgumentOutOfRangeException(nameof(takeCount), "获取数量不能为负数"); // 核心逻辑:通过取模实现循环索引 return Enumerable.Range(0, takeCount) .Select(offset => source[(startIndex + offset) % source.Count]); } }
调用示例(匹配你的需求)
IList<int> demoList = new List<int> {1,2,3,4,5,6}; // 你需要的是1基的第4位,转0基索引就是3,取10个元素 var result = demoList.CircularTake(3, 10); // 输出结果:4, 5, 6, 1, 2, 3, 4, 5, 6, 1 Console.WriteLine(string.Join(", ", result));
方案2:无限循环迭代实现
如果需要持续迭代不需要提前指定数量,可以用无限序列的实现,用的时候再通过Take指定要取的数量即可:
public static IEnumerable<T> InfiniteCircular<T>(this IList<T> source, int startIndex = 0) { if (source == null) throw new ArgumentNullException(nameof(source)); if (source.Count == 0) throw new ArgumentException("集合不能为空", nameof(source)); if (startIndex < 0 || startIndex >= source.Count) throw new ArgumentOutOfRangeException(nameof(startIndex), "起始索引超出集合范围"); int currentIndex = startIndex; while (true) { yield return source[currentIndex]; currentIndex = (currentIndex + 1) % source.Count; } } // 调用示例 var result = demoList.InfiniteCircular(3).Take(10);
内容的提问来源于stack exchange,提问作者user1027620
相关产品推荐
相关产品推荐

