2011-10-12 15 views
6

Jak uzyskać elementy kolumny z poszarpanej tablicy jako płaską tablicę za pomocą Linq ????C# Używanie Linq do pobrania kolumny z poszarpanej tablicy

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; 
+3

Mmh ... czy mógłbyś podać przykład danych wejściowych i pożądanych wyników? – digEmAll

+1

Podaj deklarację macierzy, którą chcesz spłaszczyć. – sll

+0

Przepraszam, że musiałem zapomnieć ... – nixgadgets

Odpowiedz

11

To tylko:

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

Oczywiście lepiej jest sprawdzić, czy x nie jest poza zasięgiem przed kwerendy LINQ.

W każdym razie, biorąc pod uwagę, że pracujesz na macierzy, dla większej przejrzystości możesz przełączyć się na bidimensional array zamiast poszarpanej tablicy (więc nie ma wątpliwości co do rozmiaru 2 wymiarów).

Zamiast tego, jeśli wydajność naprawdę ma dla ciebie znaczenie, używaj poszarpanych tablic, które wydają się być trochę szybsze niż układy dwuwymiarowe (np. LINK1, LINK2).

+0

Moim zdaniem byłoby to lepsze: '_matrix.Where (array => array.Length> index). Wybierz (array => array [ index]) ' –

+0

@YuriyRozhovetskiy: faktycznie tę kontrolę można wykonać przed zapytaniem, ponieważ ta poszarpana tablica ma zawsze taką samą liczbę kolumn po konstrukcji. – digEmAll

+0

@digEmAll dlaczego mówisz, że wiele tablic jest lepszych niż poszarpane w moim przypadku ???? – nixgadgets

0
var q = from row in jagged 
    from value in row 
    where value == anyvalue 
    select value; 

każdym razie, dlaczego chcesz używać LINQ? stosując klasyczne dla poprawi wydajność i ułatwić debugowanie

+0

Twoja klauzula where działa na wartości, ale aby wybrać zawsze tę samą kolumnę, myślę, że powinna działać na indeksie. – digEmAll

+0

Ogólnie użyłbym klasyki, dla której jest szybsze i łatwiejsze do debugowania. Powinieneś używać LINQ do obiektu tylko w celu poprawienia czytelności, ponieważ ogólnie rzecz biorąc klasyczne jest znacznie szybsze. –

1
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(); 
Powiązane problemy