如何将sorted list拆分为n等份?现有Split方法不符合预期
问题分析
原Split方法的问题在于用i++ % parts分组,这会把元素按间隔分配到各组,而不是按连续顺序拆分。比如输入0-17时,原方法会生成[0,3,6,...,15]、[1,4,...,16]、[2,5,...,17],完全不符合连续分段的需求。
修正后的实现
下面是满足需求的Split扩展方法:
static class LinqExtensions { public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts) { if (parts <= 0) throw new ArgumentOutOfRangeException(nameof(parts), "分段数必须大于0"); var items = list.ToList(); int count = items.Count; if (count == 0) yield break; int baseSize = count / parts; int remainder = count % parts; int currentIndex = 0; // 处理前parts-1个分段,每个为基础长度 for (int i = 0; i < parts - 1; i++) { yield return items.GetRange(currentIndex, baseSize); currentIndex += baseSize; } // 最后一个分段包含剩余所有元素(基础长度+余数) yield return items.GetRange(currentIndex, baseSize + remainder); } }
关键说明
- 转List处理:
IEnumerable<T>无法直接获取元素数量和随机访问,转成List<T>能更高效地完成分段截取。 - 分段大小计算:
baseSize是总元素数除以分段数的整数部分,作为前parts-1个分段的固定长度。remainder是总元素数对分段数取余的结果,这部分会全部加到最后一个分段的长度里。
- 循环分段逻辑:前
parts-1个分段按固定长度截取,最后一个分段直接取剩余所有元素,确保余数集中在最后一组。
测试验证
用你提供的测试代码运行修正后的方法:
- 输入0-17(共18个元素)、
parts=3时,会得到三个各含6个元素的连续分组,完全符合预期。 - 若输入0-18(共19个元素)、
parts=3时,前两组各6个元素,最后一组7个元素,余数部分正确归入最后一组。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

