如何获得具有可变步数的可枚举范围
Posted
技术标签:
【中文标题】如何获得具有可变步数的可枚举范围【英文标题】:How to get enumerable range with a variable step count 【发布时间】:2020-03-31 07:13:24 【问题描述】:我正在尝试获取具有可变步数的最小值和最大值的列表。
例如: 如果我将最小值设置为 10,000,最大值设置为 150,000,步数设置为 20,000。我应该能够得到 [10000,30000,50000,70000,...,150000] 的列表。
如果步数设置为 15,000 则类似 - 我应该将列表设为 [10000,25000,40000,...,145000]
int min = 10000;
int max = 150000;
int step = 20000;
var result = Enumerable.Range( min, max).Where(i => i<= max && (i % step == 0));
foreach (int num in result) Console.WriteLine(num); // output: [20000,40000,60000,80000,100000,120000,140000]
由于我使用模运算符来使零值相等,因此它会跳过范围内的第一个值并给我上述结果而不是 [10000,30000,..,150000]。 由于我是 C# 编程的新手,任何人都可以用上面的代码纠正我以获得所需的输出。
PS:我已经参考了这个帖子How to get alternate numbers using Enumerable.Range?,但找不到答案。
【问题讨论】:
上述***.com/questions/4142543/… 的答案非常适合这里。您是否尝试过那里的所有答案?什么不适合你? 将最大值设置为:((150000-10000)/20000) + 1。然后我使用:min + (i * 20000) 这个链接和我在描述中提到的一样。我已经试过了,没有解决我的问题 【参考方案1】:创建自定义迭代器可能比重用现有的Enumerable.Range
方法更容易。
public static IEnumerable<int> Range(int min, int max, int step)
for (int i = min; i <= max; i = checked(i + step)) yield return i;
【讨论】:
鉴于您对 Range 答案的评论以及其他同意,Range 是一种方法而不是您提供的方法似乎很奇怪,因为这对所有情况都更好,只要您定义步长默认为 1,最小值为 1。【参考方案2】:你只需要修改你的 Linq 语句中的 where 条件:
var result = Enumerable.Range(min, max - min + 1).Where(i => (i - min) % step == 0);
当i
与step
的模数是否为0 相等时,您忘记减去起始值min
。通过减去min
,您可以偏移模计算以与i
偏移min
的值进行比较,而不是使用i
。
步长为 20,000 时的输出:
10000
30000
50000
70000
90000
110000
130000
150000
步长为 15,000 时的输出:
10000
25000
40000
55000
70000
85000
100000
115000
130000
145000
【讨论】:
感谢您解释和纠正我的答案。它奏效了:) 这是相当低效的。step
越大,效率越低。
@TheodorZoulias 我有点怀疑在 OP 查询的情况下是否可以衡量任何性能影响。您究竟是如何衡量其性能的?
我没有测量它,但我很确定它是低效的,因为我知道它是如何在内部实现的。您正在做的是在循环中增加一个计数器,并每 20,000 个循环产生一个值(或 step
是什么)。以 1,000,000,000 的步长进行成像...以上是关于如何获得具有可变步数的可枚举范围的主要内容,如果未能解决你的问题,请参考以下文章
如何在带有 Flutter 的可滚动视图中拥有具有可变高度内容的 TabView?
如何在具有颤动的可滚动视图中使用具有可变高度内容的TabView?