bud*_*udi 5 c# python ienumerable range
是否有与Python 的rangestep等效的 C# ?
文档:
对于正数
step,范围的内容r由公式r[i] = start + step*iwherei >= 0和确定r[i] < stop。对于负数
step,范围的内容仍然由公式确定r[i] = start + step*i,但约束条件是i >= 0和r[i] > stop。
例子:
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
Run Code Online (Sandbox Code Playgroud)
我会采用两种方法实现。第一个用于参数验证并提供默认值:
public static IEnumerable<int> Range(int start, int stop, int step = 1)
{
if (step == 0)
throw new ArgumentException(nameof(step));
return RangeIterator(start, stop, step);
}
Run Code Online (Sandbox Code Playgroud)
这是具有延迟执行的迭代器所必需的。否则,在执行迭代器之前您不会验证参数。这可能会在您获得迭代器引用很长时间后发生。以及迭代器本身(实际上,在 C# 7 中,您可以使用本地函数而不是创建单独的方法):
private static IEnumerable<int> RangeIterator(int start, int stop, int step)
{
int x = start;
do
{
yield return x;
x += step;
if (step < 0 && x <= stop || 0 < step && stop <= x)
break;
}
while (true);
}
Run Code Online (Sandbox Code Playgroud)
为了实现 Python 的 range 行为,我们还需要一种只接受stop参数的方法。我们可以使用 C# 6 表达式主体成员来简化代码:
public static IEnumerable<int> Range(int stop) => RangeIterator(0, stop, 1);
Run Code Online (Sandbox Code Playgroud)
您还可以使用C# 6在全局范围内使用静态方法。假设具有 Range 方法描述的类名为 PythonUtils:
using static YourNamespace.PythonUtils;
Run Code Online (Sandbox Code Playgroud)
代码中的用法如下
foreach(var i in Range(0, 10, 3))
Print(i);
Run Code Online (Sandbox Code Playgroud)
您也可以使用默认值
Range(0, 10, 3) // [0,3,6,9]
Range(4, -3, -1) // [4,3,2,1,0,-1,-2]
Range(5) // [0,1,2,3,4]
Range(2, 5) // [2,3,4]
Run Code Online (Sandbox Code Playgroud)
看起来像 Pascal-case Python :)
我们可以实现一个static实用程序类来处理这个问题。
为了完整起见,此解决方案模仿 Pythonrange对于一个参数 ( stop)、两个参数 ( start, stop) 和三个参数 ( start, stop, step) 的行为:
using System;
using System.Collections.Generic;
public static class EnumerableUtilities
{
public static IEnumerable<int> RangePython(int start, int stop, int step = 1)
{
if (step == 0)
throw new ArgumentException("Parameter step cannot equal zero.");
if (start < stop && step > 0)
{
for (var i = start; i < stop; i += step)
{
yield return i;
}
}
else if (start > stop && step < 0)
{
for (var i = start; i > stop; i += step)
{
yield return i;
}
}
}
public static IEnumerable<int> RangePython(int stop)
{
return RangePython(0, stop);
}
}
Run Code Online (Sandbox Code Playgroud)
步骤的用法示例:
foreach (var i in EnumerableUtilities.RangePython(0, 10, 3))
{
Console.WriteLine(i);
}
Run Code Online (Sandbox Code Playgroud)
输出:
0
3
6
9
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5989 次 |
| 最近记录: |