Como criar uma sequência de inteiros em C #?

119

F # possui sequências que permitem criar sequências:

seq { 0 .. 10 }

Crie uma sequência de números de 0 a 10.

Existe algo semelhante em C #?

Budda
fonte

Respostas:

206

Você pode usar Enumerable.Range(0, 10);. Exemplo:

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

Página do MSDN aqui .

alexn
fonte
66
Nota: Isso cria uma sequência começando em 0 com 10 itens (terminando em 9). Se você quiser de 0 a 10, o segundo parâmetro será 11. E se você precisar de uma matriz real e não IEnumerable<int>, inclua uma chamada .ToArray().
Anthony Pegram
19

Você pode criar uma função simples. Isso funcionaria para uma sequência mais complicada. Caso contrário, o Enumerable.Rangedeve servir.

IEnumerable<int> Sequence(int n1, int n2)
{
    while (n1 <= n2)
    {
        yield return  n1++;
    }
}
Josiah Ruddell
fonte
Por "mais complicado", você quer dizer apenas "onde você começou e terminou à mão em vez do número de elementos"? Caso contrário, estou perdendo o seu significado. 🤔
ruffin
1
Eu acredito que estava considerando OddSequence EvenSequenceou outros intervalos personalizados. if (++n1 % 2 == 0) yield return n1, por exemplo. Já se passaram alguns dias;)
Josiah Ruddell
Ha, sim, um ou dois dias, suponho. Ou alguns milhares. ; ^)
ruffin
7

Projeção Linq com a sobrecarga do indexador raramente usada (i) :

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

Eu prefiro este método por sua flexibilidade.

Por exemplo, se eu quiser pares:

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

Ou se eu quiser incrementos de 5 minutos de uma hora:

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

Ou strings:

(new int[12]).Select((item,i) => "Minute:" + i*5)
b_levitt
fonte
Eu realmente gosto disso, mas também parece um pouco "hacky" ao mesmo tempo!
Zimano
lol :-) É apenas um ótimo uso criativo da sobrecarga do indexador!
Zimano
2

Em C # 8.0 você pode usar índices e intervalos

Por exemplo:

var seq = 0..2;
var array = new string[]
{
    "First",
    "Second",
    "Third",
};

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

Ou se você quiser criar IEnumerable<int>, você pode usar a extensão:

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

PS Mas tenha cuidado com os 'índices do fim' . Por exemplo, o método de extensão ToEnumerable não está funcionando var seq = ^2..^0.

Evgeniy Mironov
fonte
1

Minha implementação:

    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;
        }
    }
Ditador
fonte
0

Respondido originalmente aqui .


Se você quiser enumerar uma sequência de números ( IEnumerable<int>) de 0para uma variável end, tente

Enumerable.Range(0, ++10);

Na explicação, para obter uma sequência de números de 0 a 10, você deseja que a sequência comece em 0 (lembrando que existem 11 números entre 0 e 10, inclusive).


Se você quiser uma série linear ilimitada, pode escrever uma função como

IEnumerable<int> Series(int k = 0, int n = 1, int c = 1)
{
    while (true)
    {
        yield return k;
        k = (c * k) + n;
    }
}

que você poderia usar como

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

Se você quiser uma função que possa chamar repetidamente para gerar números crescentes, talvez queira algo como.

using System.Threading;

private static int orderNumber = 0;

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

Quando você ligar, Seq()ele retornará o próximo número do pedido e aumentará o contador.

Jodrell
fonte
0

Eu tenho essas funções no meu código

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;
        }
    }

Isso ajuda a reduzir parte do código (i).

haiduong87
fonte