8

How do I get elements of a column from a jagged array as a flat array using Linq ????

public class Matrix<T>
{
    private readonly T[][] _matrix;

    public Matrix(int rows, int cols)
    {
        _matrix = new T[rows][];
        for (int r = 0; r < rows; r++)
        {
            _matrix[r] = new T[cols];
        }
    }

    public T this[int x, int y]
    {
        get { return _matrix[x][y]; }
        set { _matrix[x][y] = value; }
    }

    // Given a column number return the elements
    public IEnumerable<T> this[int x]
    {
        get
        {
        }
    }
}

Matrix<double> matrix = new Matrix<double>(6,2);
matrix[0, 0] = 0;
matrix[0, 1] = 0;
matrix[1, 0] = 16.0;
matrix[1, 1] = 4.0;
matrix[2, 0] = 1.0;
matrix[2, 1] = 6.0;
matrix[3, 0] = 5.0;
matrix[3, 1] = 7.0;
matrix[4, 0] = 1.3;
matrix[4, 1] = 1.0;
matrix[5, 0] = 1.5;
matrix[5, 1] = 4.5;
nixgadget
  • 6,983
  • 16
  • 70
  • 103

3 Answers3

13

It's just:

public IEnumerable<T> this[int x]
{
    get
    {
       return _matrix.Select(row => row[x]);
    }
}

Of course it's better to check if x is not out of the range before the LINQ query.

Anyway, given that you're working on a matrix, for more clarity you could switch to a bidimensional array instead of a jagged array (so no doubt about the size of the 2 dimensions).

Instead, if performance really really matters for you, keep using jagged arrays which seem to be a bit faster than bidimensional arrays (e.g LINK1, LINK2).

Community
  • 1
  • 1
digEmAll
  • 56,430
  • 9
  • 115
  • 140
  • In my opinion this would be better: `_matrix.Where(array => array.Length > index).Select(array => array[index])` – Yuriy Rozhovetskiy Oct 12 '11 at 11:15
  • @YuriyRozhovetskiy: actually this control can be made before the query, because this jagged array has always the same number of columns by construction. – digEmAll Oct 12 '11 at 11:39
  • @digEmAll i see your point. is it because jaggeds can have mixed sizes ? – nixgadget Oct 12 '11 at 12:07
  • @kuzyt: yes, but it's just a matter of syntax/clarity. If performance really matters for you, jagged arrays seems to be a bit faster than multidimensional array (check my edit). – digEmAll Oct 12 '11 at 12:31
2
var source = new int[3][] {
    Enumerable.Range(1,3).ToArray(),
    Enumerable.Range(10,5).ToArray(),
    Enumerable.Range(100,10).ToArray()
};

int index = 0;

var result = (from array in source
                from item in array
                group item by Array.IndexOf(array, item) into g
                where g.Key == index
                select g.ToArray()).FirstOrDefault();
Yuriy Rozhovetskiy
  • 22,270
  • 4
  • 37
  • 68
0
var q = from row in jagged 
    from value in row 
    where value == anyvalue 
    select value; 

anyway why do you want to use LINQ? using a classic for it will improve the performance and make easier debugging

Massimiliano Peluso
  • 26,379
  • 6
  • 61
  • 70
  • Your where clause works on the value, but in order to select always the same column, I think it should work on the index... – digEmAll Oct 12 '11 at 10:53
  • In general I would use a classic for which is faster and easier to debug. You should use LINQ to object only to improve readability as in general the classic for is much faster – Massimiliano Peluso Oct 12 '11 at 10:55