【问题标题】:How to create a sequence of integers in C#?如何在 C# 中创建整数序列?
【发布时间】:2022-04-22 02:47:18
【问题描述】:

F# 有 sequences 允许创建序列:

seq { 0 .. 10 }

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

C#中有类似的东西吗?

【问题讨论】:

    标签: c# .net f# sequence


    【解决方案1】:

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

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

    MSDN 页面here

    【讨论】:

    • 注意:这会创建一个从 0 开始,包含 10 个项目(以 9 结束)的序列。如果您想要 0 10,则第二个参数将是 11。如果您需要一个实际数组而不是 IEnumerable<int>,请包含一个调用 .ToArray()
    【解决方案2】:
    Enumerable.Range(0, 11);
    

    生成指定范围内的整数序列。

    http://msdn.microsoft.com/en-us/library/system.linq.enumerable.range.aspx

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 你所说的“更复杂”是指“你在哪里开始和结束方便而不是元素的数量”?否则我会错过你的意思。 ?
      • 我相信我正在考虑 OddSequence EvenSequence 或其他自定义范围。例如if (++n1 % 2 == 0) yield return n1。已经好几天了;)
      • 哈,是的,我想一两天。或者几千。 ;^)
      【解决方案4】:

      Linq 投影与很少使用的indexer overload (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)
      

      【讨论】:

      • 我真的很喜欢这个,但同时也感觉有点hacky!
      • 大声笑 :-) 这只是索引器重载的一个很好的创造性使用!
      • 我觉得Enumerable.Range(0, 12).Select( i =&gt; "Minute:" + i*5 )的可读性更强。
      【解决方案5】:

      在 C# 8.0 中,您可以使用 Indices and ranges

      例如:

      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&lt;int&gt;,那么你可以使用扩展:

      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
      

      附:但要小心'indexes from end'。例如,ToEnumerable 扩展方法不适用于var seq = ^2..^0

      【讨论】:

        【解决方案6】:

        我的实现:

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

        【讨论】:

          【解决方案7】:

          原为answered here


          如果你想枚举从0到变量end的数字序列(IEnumerable&lt;int&gt;),那么试试

          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 ZeroTo1000 = Series().Take(11);
          

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

          using System.Threading;
          
          private static int orderNumber = 0;
          
          int Seq()
          {
              return Interlocked.Increment(ref orderNumber);
          }
          

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

          【讨论】:

            【解决方案8】:

            我的代码中有这些函数

            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) 代码。

            【讨论】:

              【解决方案9】:

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

              using System.Collections.Generic;
              using System.Linq;
              
              IEnumerable<int> numbersToPrint = Enumerable.Range(1, 11);
              

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

              【讨论】:

                猜你喜欢
                • 2016-12-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-01-20
                • 1970-01-01
                相关资源
                最近更新 更多