Jak utworzyć sekwencję liczb całkowitych w C #?

119

F # ma sekwencje, które pozwalają tworzyć sekwencje:

seq { 0 .. 10 }

Utwórz ciąg liczb od 0 do 10.

Czy jest coś podobnego w C #?

Budda
źródło

Odpowiedzi:

206

Możesz użyć Enumerable.Range(0, 10);. Przykład:

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

Strona MSDN tutaj .

alexn
źródło
66
Uwaga: Tworzy to sekwencję zaczynającą się od 0 z 10 elementami (kończącą się na 9). Jeśli chcesz mieć od 0 do 10, drugi parametr będzie miał wartość 11. A jeśli potrzebujesz rzeczywistej tablicy, a nie IEnumerable<int>, dołącz wywołanie .ToArray().
Anthony Pegram,
19

Możesz stworzyć prostą funkcję. To zadziałałoby w przypadku bardziej skomplikowanej sekwencji. W przeciwnym razie Enumerable.Rangepowinno wystarczyć.

IEnumerable<int> Sequence(int n1, int n2)
{
    while (n1 <= n2)
    {
        yield return  n1++;
    }
}
Josiah Ruddell
źródło
Czy przez „bardziej skomplikowane” masz na myśli tylko „miejsce, w którym zacząłeś i kończysz poręczny zamiast liczby elementów”? W przeciwnym razie brakuje mi twojego znaczenia. 🤔
ruffin
1
Myślę, że rozważałem OddSequence EvenSequencelub inne niestandardowe zakresy. if (++n1 % 2 == 0) yield return n1, na przykład. Minęło już kilka dni;)
Josiah Ruddell
Ha, tak, chyba jeden lub dwa dni. Albo kilka tysięcy. ; ^)
ruffin
7

Projekcja Linq z rzadko używanym przeciążeniem indeksatora (i) :

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

Wolę tę metodę ze względu na jej elastyczność.

Na przykład, jeśli chcę parzyste:

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

Lub jeśli chcę 5-minutowe odstępy co godzinę:

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

Lub struny:

(new int[12]).Select((item,i) => "Minute:" + i*5)
b_levitt
źródło
Naprawdę to lubię, ale jednocześnie wydaje mi się trochę hacky!
Zimano
lol :-) To po prostu świetne kreatywne wykorzystanie przeciążenia indeksatora!
Zimano
2

W C # 8.0 możesz używać indeksów i zakresów

Na przykład:

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

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

Lub jeśli chcesz stworzyć IEnumerable<int>, możesz użyć rozszerzenia:

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 Ale uważaj na „indeksy od końca” . Na przykład metoda rozszerzenia ToEnumerable nie działa z var seq = ^2..^0.

Evgeniy Mironov
źródło
1

Moja realizacja:

    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;
        }
    }
Dicaste
źródło
0

Pierwotnie odpowiedział tutaj .


Jeśli chcesz wyliczyć sekwencję liczb ( IEnumerable<int>) od 0do zmiennej end, spróbuj

Enumerable.Range(0, ++10);

Aby uzyskać ciąg liczb od 0 do 10, chcesz, aby ciąg zaczynał się od 0 (pamiętając, że istnieje 11 liczb od 0 do 10 włącznie).


Jeśli chcesz mieć nieograniczony szereg liniowy, możesz napisać funkcję taką jak

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

których możesz użyć jak

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

Jeśli potrzebujesz funkcji, którą możesz wywoływać wielokrotnie, aby wygenerować rosnące liczby, być może potrzebujesz czegoś podobnego.

using System.Threading;

private static int orderNumber = 0;

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

Kiedy zadzwonisz Seq(), zwróci następny numer zamówienia i zwiększy licznik.

Jodrell
źródło
0

Mam te funkcje w swoim kodzie

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

Pomaga to zmniejszyć część kodu dla (i).

haiduong87
źródło