【问题标题】:Create an array full of -1; [duplicate]创建一个充满-1的数组; [复制]
【发布时间】:2013-12-12 10:10:18
【问题描述】:

不是像 c# 通常那样从 0 开始每个值,我想知道是否有办法从像 -1 这样的特定数字开始,而不必在初始化后循环将每个 0 替换为 -1?

【问题讨论】:

  • 可能,但这里的答案更有帮助,感谢大家。

标签: c# arrays


【解决方案1】:

使用类似的东西

 var myArray =  Enumerable.Repeat(-1, 1000000).ToArray();

important note; it is slower than looping manually

【讨论】:

  • +1 表示它不是最理想的。
  • 是的,它比较慢主要是因为ToArray 不知道元素的最终数量,并且不时重新分配数组以获取更多空间用于新元素。
  • @MarcinJuraszek,我喜欢使用 ilspy 来查看幕后发生的事情,我不适合这种情况,但很高兴知道 :-)
【解决方案2】:

当然,可能。

void Main()
{
    var arr = Enumerable.Repeat(-1, 10).ToArray();  
    Console.WriteLine (arr);
}

不完全确定幕后发生了什么,因此它可能仍会循环遍历列表中的值。不过这很难避免。

不同的解决方案:

void Main()
{
    var arr = new List<int>(new int[10]).Select(x => x = -1).ToArray();
    Console.WriteLine (arr);
}

【讨论】:

  • 是的,它会在引擎盖下循环。
【解决方案3】:

你可以使用Repeat:

int[] array = Enumerable.Repeat(-1, 5).ToArray();

正如在别处提到的,这是语法糖 - 循环仍将运行,并且您将产生将生成的 IEnumerable 转换回数组的开销。

【讨论】:

    【解决方案4】:

    试试:

    int[] intArray =  Enumerable.Repeat(-1, [Length]).ToArray();
    

    【讨论】:

      【解决方案5】:

      Enumerable 类可能会有所帮助,如下所示:

      IEnumerable<int> array = Enumerable.Repeat(-1, 15);  // or whatever range you'd like
      

      【讨论】:

      • 但它并不是一个真正的数组 ;)
      【解决方案6】:

      考虑以下代码...

      items =  items.Select(s => s = -1).ToArray();
      

      祝你好运!

      【讨论】:

        【解决方案7】:

        你可以这样做:

        public static int[] Initialize( this int[] instance , int value )
        {
          if ( instance == null ) throw new ArgumentNullException("instance") ;
          for ( int i = 0 ; i < instance.Length ; ++i )
          {
            instance[i] = value ;
          }
          return instance ;
        }
        

        这会让你说类似的话

        int[] foo = new int[2048].Initialize(-1) ;
        

        通过不安全和使用指针,您可能会获得一些性能提升,因为您不会产生数组边界检查的开销,如下所示:

        public static unsafe int[] Initialize( this int[] instance , int value )
        {
          if ( instance == null ) throw new ArgumentNullException("instance") ;
          fixed ( int *addr = instance )
          {
            int *p    = addr ;
            int *pMax = addr+instance.Length ;
            while ( p < pMax )
            {
              *(p++) = value ;
            }
            return instance ;
          }
        

        如果您只想将数组设置为 -1,则可以使用 memset() 使其更快,因为我们知道所有字节都是 0xFF。所以...

            public static unsafe int[] InitializeToMinus1( this int[] instance )
            {
                if ( instance == null ) throw new ArgumentNullException("instance");
                fixed( void *p = instance )
                {
                    IntPtr    addr  = new IntPtr(p) ;
                    const int hexFF = 0x000000FF ;
                    int       bytes = instance.Length * sizeof(int) ;
                    memset( addr , hexFF , bytes ) ;
                }
                return instance ;
            }
        
            [DllImport("msvcrt.dll", EntryPoint="memset", CallingConvention=CallingConvention.Cdecl, SetLastError = false)]
            public static extern IntPtr memset( IntPtr addr , int c , int count ) ;
        

        【讨论】:

        • 感谢您的详尽回答!看起来我将不得不创建一些像这样的自定义。感谢您提供的所有示例,它们真的很有帮助,甚至没有想过使用非标准的东西来做到这一点。
        猜你喜欢
        • 1970-01-01
        • 2023-03-10
        • 2021-02-02
        • 1970-01-01
        • 2018-03-15
        • 2013-12-11
        • 2014-09-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多