Sayuri
Sayuri

Reputation: 94

accessing a whole row in an array at once

I have a two-dimensional array in C#. Later I want to access elements of the array - not only one at once, but a whole row.

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

What would be the fastest way to do this?

Upvotes: 0

Views: 1297

Answers (4)

Matthew Watson
Matthew Watson

Reputation: 109732

The quickest way to do this would probably be if you could use an array rather than a list for the result, using Buffer.BlockCopy() like so:

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

However, don't make ANY assumptions about what is faster.

Do some timings with Stopwatch for a release build to be sure.

Upvotes: 0

Mike S.
Mike S.

Reputation: 2111

One way to do this can be not making two dimensional array (which is possibly internally one-dimensional array with access like array[x,y] = __array[x + width * y] but using array of arrays (I'll dont write the exact syntax to do this in C#, because I'm not doint C# for about 5 years, maybe something like int[][] arr = new int[3]; arr[0] = new int[3]; arr[1] = new int[3]; arr[2] = new int[3]).

Then you will be able to address the whole column using arr[n]

Upvotes: 0

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101701

Using Linq you can achieve it like this:

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

Upvotes: 3

Servy
Servy

Reputation: 203827

You don't really have any choice other than to iterate through all of the columns, looking at each of the values in the row:

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

Upvotes: 1

Related Questions