Как создать последовательность целых чисел на C #?

119

В F # есть последовательности, которые позволяют создавать последовательности:

seq { 0 .. 10 }

Создайте последовательность чисел от 0 до 10.

Есть ли что-то подобное в C #?

Budda
источник

Ответы:

206

Вы можете использовать Enumerable.Range(0, 10);. Пример:

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

Страница MSDN здесь .

AlexN
источник
66
Примечание. Это создает последовательность, начинающуюся с 0 и состоящую из 10 элементов (заканчивающуюся 9). Если вы хотите от 0 до 10, вторым параметром будет 11. И если вам нужен реальный массив, а нет IEnumerable<int>, включите вызов .ToArray().
Энтони Пеграм,
19

Вы можете создать простую функцию. Это подойдет для более сложной последовательности. В противном случае так и 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, например. Прошло несколько дней;)
Джозайя Радделл
Ха, да, один или два дня, я полагаю. Или несколько тысяч. ; ^)
ruffin
7

Проекция Linq с редко используемой перегрузкой индексатора (i) :

(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)
b_levitt
источник
Мне это очень нравится, но в то же время это кажется немного взломанным!
Зимано,
lol :-) Это просто отличное творческое использование перегрузки индексатора!
Зимано,
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

PS Но будьте осторожны с «индексами с конца» . Например, метод расширения 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;
        }
    }
Dicaste
источник
0

Первоначально ответили здесь .


Если вы хотите перечислить последовательность чисел ( IEnumerable<int>) от 0до переменной end, попробуйте

Enumerable.Range(0, ++10);

В пояснении, чтобы получить последовательность чисел от 0 до 10, вы хотите, чтобы последовательность начиналась с 0 (помня, что существует 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 ZeroTo1000 = Series().Take(11);

Если вам нужна функция, которую можно вызывать несколько раз для генерации увеличивающихся чисел, возможно, вам нужно что-то вроде.

using System.Threading;

private static int orderNumber = 0;

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

При вызове Seq()он вернет номер следующего заказа и увеличит счетчик.

Jodrell
источник
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).

haiduong87
источник