【问题标题】:accessing a whole row in an array at once一次访问数组中的整行
【发布时间】:2014-09-25 13:53:32
【问题描述】:

我在 C# 中有一个二维数组。稍后我想访问数组的元素——不仅是一次,而且是一整行。

int[,] example = { { 1, 2, 3 }, { 4, 5, 6 }, {7, 8, 9} }
list<int> extract = ??? row1 of example ???

最快的方法是什么?

【问题讨论】:

  • 如果您正在寻找最快的方法,请尝试所有可以解决问题的方法并进行比较。

标签: c# arrays


【解决方案1】:

使用 Linq 你可以这样实现:

List<int> extract = Enumerable.Range(0, example.GetLength(1))
       .Select(x => example[0,x])
       .ToList();

【讨论】:

    【解决方案2】:

    除了遍历所有列,查看行中的每个值之外,您别无选择:

    public static IEnumerable<T> GetRow<T>(this T[,] array, int row)
    {
        for (int i = 0; i < array.GetLength(1); i++)
            yield return array[row, i];
    }
    

    【讨论】:

      【解决方案3】:

      做到这一点的一种方法可以是不制作二维数组(可能是内部一维数组,具有类似array[x,y] = __array[x + width * y] 的访问权限,但使用数组数组(我不会在 C# 中编写执行此操作的确切语法,因为我已经有 5 年没有使用 C# 了,可能类似于 int[][] arr = new int[3]; arr[0] = new int[3]; arr[1] = new int[3]; arr[2] = new int[3])。

      然后您将能够使用arr[n] 处理整个列

      【讨论】:

        【解决方案4】:

        如果您可以使用数组而不是列表作为结果,最快的方法可能是使用Buffer.BlockCopy(),如下所示:

        using System;
        using System.Linq;
        
        namespace Demo
        {
            internal class Program
            {
                private static void Main()
                {
                    int[,] example =
                    {
                        { 1,  2,  3,  4}, 
                        { 5,  6,  7,  8}, 
                        { 9, 10, 11, 12},
                        {13, 14, 15, 16},
                        {17, 18, 19, 20},
                    };
        
                    int sourceColumns = example.GetUpperBound(0);
        
                    int[] row1 = new int[sourceColumns];
        
                    int requiredRow = 3;
                    int sourceOffset = requiredRow * sourceColumns * sizeof(int);
                    int sourceWidthBytes = sourceColumns*sizeof (int);
        
                    Buffer.BlockCopy(example, sourceOffset, row1, 0, sourceWidthBytes);
        
                    // Now row1 contains 13, 14, 15, 16. Prove it by writing to display:
        
                    Console.WriteLine(string.Join(", ", row1));
        
                    // If you really must have a List<int>
                    // (but this will likely make it much slower than just
                    // adding items to the list on an element-by-element basis):
        
                    var list = new List<int>(row1);
        
                    // Do something with list.
                }
            }
        }
        

        但是,不要对更快的做出任何假设。

        使用Stopwatch 进行一些计时以确保发布版本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-23
          • 1970-01-01
          • 1970-01-01
          • 2021-12-11
          • 2018-09-13
          相关资源
          最近更新 更多