User1551892
User1551892

Reputation: 3384

How to get a complete row or column from 2D array in C#

I do not want to use a jagged array and I have a 2D array and I want to get a complete column or row without looping through it. Does anyone have an idea how it can be done.

double [,]  array = new double [3,3] ;

1   2   3 
4   5   6

Out: 1   2   3  or 2   5 

Upvotes: 76

Views: 140602

Answers (9)

0x777
0x777

Reputation: 945

Try this implementation:

static T[] GetSlice<T>(T[,] array, int row)
{
    int cols = array.GetLength(1);
    var slice = new T[cols];

    for (int col = 0; col < cols; col++)
    {
        slice[col] = array[row, col];
    }

    return slice;
}

Upvotes: 0

Alex23
Alex23

Reputation: 441

As of March 2021, you can now use the very cool Span2D class for this!

If you are happy using spans (I highly recommend reading about them, they are awesome), you can use the following code

var span2D = new Span2D<double>(array);

//Gets the first row and returns a span of it
var rowSpan = span2D.GetRowSpan(0);

foreach(var number in rowSpan)
{
    //Do something with numbers
}

//Gets the 2nd Column as a RefEnumerable and converts it to an array
var column = span2D.GetColumn(1).ToArray();

Upvotes: 12

E.Lahu
E.Lahu

Reputation: 408

Here is how i have done it you can use

GetLength(0)

to get the columns and use

GetLength(1)

to get the rows of the 2 Dimensional array and you loop thru it with the for loop if any one else needs this.

string text = "";
for (int i = 0; i < array.GetLength(0); i++)
{
   text += Convert.ToString(array[i, 2]) + "\n";
}

Upvotes: 0

andrew pate
andrew pate

Reputation: 4297

My use case differs from the question, but is similar. I needed a 2D array of float[2] arrays, that I was using to represent complex numbers.

float[,,] myarray = new float[100,100,2];
float[] result = myarray[1,1];   <-- fails to compile needs all 3 coordinates

The jagged array Simmon mentioned provided the solution.

float[,][] myarray = new float[100,100][];
...
myarray[x,y] = new float[2];  <-- Initialise all elements of jagged 2D array in loop
...
float[] result = [100,100];

Upvotes: -1

Shimon Doodkin
Shimon Doodkin

Reputation: 4579

what is needed is a jagged array (not a multidimensional array)

https://msdn.microsoft.com/en-us/library/2s05feca.aspx

int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };

full example with columns:

using System;
using System.Collections.Generic;

namespace Rextester
{
    public class Program
    {

        public static T[] column<T>(T[][] jaggedArray,int wanted_column)
        {
            T[] columnArray = new T[jaggedArray.Length];
            T[] rowArray;
            for(int i=0;i<jaggedArray.Length;i++)
            {
                rowArray=jaggedArray[i];
                if(wanted_column<rowArray.Length)
                    columnArray[i]=rowArray[wanted_column];
            }
            return columnArray;
        }

        public static void Main(string[] args)
        {
            //Your code goes here
                int[][] jaggedArray = new int[3][];
                jaggedArray[0] = new int[5];
                jaggedArray[1] = new int[] { 0, 2, 4, 6 };
                jaggedArray[2] = new int[] { 11, 22 };

                Console.WriteLine("Hello, world!");
                Console.WriteLine(string.Join(" ",jaggedArray[1]));
                Console.WriteLine(string.Join(" ",column(jaggedArray,1)));
        }
    }
}

similar idea, using extensions:

using System;
using System.Collections.Generic;

namespace Rextester
{
    public static class MyExtensions
    {
        public static string Extend(this Array array)
        {
            return "Yes, you can extend an array";
        }

        public static T[] column<T>(this T[,] multidimArray,int wanted_column)
        {
            int l=multidimArray.GetLength(0);
            T[] columnArray = new T[l];
            for(int i=0;i<l;i++)
            {
              columnArray[i]=multidimArray[i,wanted_column];
            }
            return columnArray;
        }

        public static T[] row<T>(this T[,] multidimArray,int wanted_row)
        {
            int l=multidimArray.GetLength(1);
            T[] rowArray = new T[l];
            for(int i=0;i<l;i++)
            {
              rowArray[i]=multidimArray[wanted_row,i];
            }
            return rowArray;
        }


    } 

    public class Program
    {


        public static void Main(string[] args)
        {
                Console.WriteLine("Hello, world!");

                int [,] multidimArray = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
                Console.WriteLine(string.Join(" ",multidimArray.column(0)));
                Console.WriteLine(string.Join(" ",multidimArray.row(0)));

        }
    }
}

Upvotes: 0

Matthew Watson
Matthew Watson

Reputation: 109812

You can optimise it for getting rows by using Buffer.BlockCopy(), but to get a column you'll have to loop. Buffer.BlockCopy() ultimately uses a processor instruction to copy a block of memory, so it is pretty fast.

It's convenient to put the code into an extension method to make it easier to call. Note that Buffer.BlockCopy() can only be used on arrays of primitive types, i.e. int, double, char etc. This does NOT include string.

Here's a compilable example:

using System;
using System.Linq;
using System.Runtime.InteropServices;

namespace ConsoleApplication4
{
    public static class Program
    {
        private static void Main()
        {
            var array = new [,]
            {
                {0.1, 0.2, 0.3, 0.4, 0.5},
                {1.1, 1.2, 1.3, 1.4, 1.5},
                {2.1, 2.2, 2.3, 2.4, 2.5},
                {3.1, 3.2, 3.3, 3.4, 3.5},
            };

            var row = array.GetRow(2);

            // This prints 2.1, 2.2, 2.3, 2.4, 2.5

            Console.WriteLine(string.Join(", ", row.Select(element => element.ToString())));
        }
    }

    public static class ArrayExt
    {
        public static T[] GetRow<T>(this T[,] array, int row)
        {
            if (!typeof(T).IsPrimitive)
                throw new InvalidOperationException("Not supported for managed types.");

            if (array == null)
                throw new ArgumentNullException("array");

            int cols = array.GetUpperBound(1) + 1;
            T[] result = new T[cols];

            int size;

            if (typeof(T) == typeof(bool))
                size = 1;
            else if (typeof(T) == typeof(char))
                size = 2;
            else
                size = Marshal.SizeOf<T>();

            Buffer.BlockCopy(array, row*cols*size, result, 0, cols*size);

            return result;
        }
   }
}

Upvotes: 27

Alex Podles
Alex Podles

Reputation: 1209

To get a specific row or column from the multidimensional array you can use some LINQ:

public class CustomArray<T>
{
    public T[] GetColumn(T[,] matrix, int columnNumber)
    {
        return Enumerable.Range(0, matrix.GetLength(0))
                .Select(x => matrix[x, columnNumber])
                .ToArray();
    }

    public T[] GetRow(T[,] matrix, int rowNumber)
    {
        return Enumerable.Range(0, matrix.GetLength(1))
                .Select(x => matrix[rowNumber, x])
                .ToArray();
    }
}

Upvotes: 117

Pontios
Pontios

Reputation: 2394

an alternative way you can do it is by using a List instead of an array.

Specifically in your case you'd do something like that:

  1. Initially create an inner class that represents a tuple of the array
  2. Create a List of the inner class
  3. Populate the inner class
  4. Get the row that contains something specific
  5. Get the column that contains something specific
public static void Main(string[] args)
{
    // #2 -- Instantiate List of myClass
    List<myClass> myList = new List<myClass>();
    //
    // #3 -- Populate the list
    myList.Add(new myClass(1,2,3));           
    myList.Add(new myClass(3,4,5));
    myList.Add(new myClass(5,6,6));
    //
    // #4 -- Get the line where a == 1
    myList.Find(x=>x.a == 1);
    //
    // #5 -- Get column b
    myList.Select(x=>x.b);
}
// #1 -- Create the inner class
public class myClass
{
    public int a;
    public int b;
    public int c;
    public myClass(int a, int b, int c)
    {
        this.a =a;
        this.b =b;
        this.c =c;
    }
}

Upvotes: 0

SuncoastOwner
SuncoastOwner

Reputation: 263

if you know the index of the numbers to output..then you don't need to use a loop to get the output desired...

double[,] array = new double[3,3] {{1,2,3}, {4,5,6}, {7,8,9}}; 

int firstNum = array[0,1];
int secondNum = array[1,1];

this will get 2, 5

Upvotes: -6

Related Questions