如何在C#中创建整数序列?

133

F#有sequences,可以创建序列:

seq { 0 .. 10 }

创建从0到10的数字序列。

C#中是否有类似的功能?

9个回答

233

你可以使用Enumerable.Range(0, 10);。示例:

var seq = Enumerable.Range(0, 10);

MSDN页面在这里


76
注意:这将创建一个从0开始的序列,包含10个项目(以9结束)。如果您想要0到10的序列,第二个参数应该是11。如果您需要一个实际的数组而不是IEnumerable<int>,请包括调用.ToArray() - Anthony Pegram

42

20

你可以创建一个简单的函数。这个函数可以适用于更复杂的序列,否则可以使用Enumerable.Range

IEnumerable<int> Sequence(int n1, int n2)
{
    while (n1 <= n2)
    {
        yield return  n1++;
    }
}

“更加复杂”是指仅仅“有开始和结束位置而不是元素数量吗”?否则,我没有理解您的意思。 - ruffin
1
我相信我正在考虑OddSequence EvenSequence或其他自定义范围。例如,if (++n1 % 2 == 0) yield return n1。已经过了几天;) - Josiah Ruddell
1
哈,是啊,我想大概需要一两天时间。或者几千年。;^) - ruffin

11

使用很少见的索引器重载 (i) 进行 Linq 投影:

(new int[11]).Select((o,i) => i)

我喜欢这种方法,因为它很灵活。

例如,如果我想要偶数:

(new int[11]).Select((item,i) => i*2)

或者,如果我想要每小时的5分钟增量:

(new int[12]).Select((item,i) => i*5)

或字符串:

(new int[12]).Select((item,i) => "Minute:" + i*5)

我真的很喜欢这个,但同时也感觉有点hacky! - Zimano
哈哈,这只是索引器重载的巧妙创意运用! - Zimano
2
我觉得使用 Enumerable.Range(0, 12).Select( i => "Minute:" + i*5 ) 更易读。 - Matt Baran

2
在 C# 8.0 中,您可以使用 索引和范围
例如:
var seq = 0..2;
var array = new string[]
{
    "First",
    "Second",
    "Third",
};

foreach(var s in array[seq])
{
    System.Console.WriteLine(s);
}
// Output: First, Second

或者,如果您想创建 IEnumerable<int>,则可以使用扩展方法:

public static IEnumerable<int> ToEnumerable(this Range range)
{
   for (var i = range.Start.Value; i < range.End.Value; i++)
   {
       yield return i;
   }
}
...
var seq = 0..2;

foreach (var s in seq.ToEnumerable())
{
   System.Console.WriteLine(s);
}
// Output: 0, 1

附言:但是要小心使用“从末尾开始的索引”。例如,ToEnumerable扩展方法无法与var seq = ^2..^0一起使用。

1

我的实现:

    private static IEnumerable<int> Sequence(int start, int end)
    {
        switch (Math.Sign(end - start))
        {
            case -1:
                while (start >= end)
                {
                    yield return start--;
                }

                break;

            case 1:
                while (start <= end)
                {
                    yield return start++;
                }

                break;

            default:
                yield break;
        }
    }

0

最初在这里回答


如果你想枚举从0到10的数字序列(IEnumerable<int>),可以尝试以下代码:

Enumerable.Range(0, ++10);

解释一下,如果你想要得到一个从 0 到 10 的数字序列,你需要让这个序列以 0 开始(记住,在 0 和 10 之间有 11 个数字,包括 0 和 10)。


如果您想要一个无限的线性序列,您可以编写一个类似以下的函数:
IEnumerable<int> Series(int k = 0, int n = 1, int c = 1)
{
    while (true)
    {
        yield return k;
        k = (c * k) + n;
    }
}

你可以像这样使用

var ZeroTo10 = Series().Take(11);

如果您想要一个可重复调用以生成递增数字的函数,也许您需要类似以下的东西。
using System.Threading;

private static int orderNumber = 0;

int Seq()
{
    return Interlocked.Increment(ref orderNumber);
}

当您调用Seq()时,它将返回下一个订单号并递增计数器。

0

如果您希望将生成的序列保存在变量中:

using System.Collections.Generic;
using System.Linq;

IEnumerable<int> numbersToPrint = Enumerable.Range(1, 11);

这在上面展示的其他解决方案中是隐含的,但我还明确包含了所需的命名空间,以使其按预期工作。


0

我在我的代码中有这些函数

private static IEnumerable<int> FromZero(this int count)
    {
        if (count <= 0)
            yield break;

        for (var i = 0; i < count; i++)
        {
            yield return i;
        }
    }

    private static IEnumerable<int> FromOne(this int count)
    {
        if (count <= 0)
            yield break;

        for (var i = 1; i <= count; i++)
        {
            yield return i;
        }
    }

这有助于减少一些 for(i) 代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接