2011-01-26 17 views
25

Próbuję dowiedzieć się, jak uzyskać pojedynczy wymiar z wielowymiarowej tablicy (ze względu na argument, powiedzmy, że jest 2D), mam wielowymiarową tablicę :Jak uzyskać wymiar (wycinek) z wielowymiarowej tablicy

double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } }; 

Jeśli to było postrzępione tablicy, chciałbym po prostu zadzwoń d[0] i że da mi tablicę {1, 2, 3, 4, 5}, czy istnieje sposób mogę osiągnąć to samo z 2D tablicy?

+1

Brzmi jak chcesz utworzyć tablicę, która odwołuje kawałek tablicy. Nie sądzę, że to możliwe. – Gabe

+0

@Gabe, tak, przejrzałem dokumentację i nie widziałem niczego, co pomogłoby mi uzyskać kawałek, więc zdecydowałem się potwierdzić w społeczności. Dzięki za informację! :) – Kiril

+2

Właśnie zauważyłem, że moje pytanie jest duplikatem: http://stackoverflow.com/questions/1406083/array-slice-in-c – Kiril

Odpowiedz

17

Nie. Można oczywiście napisać klasę otoki, która reprezentuje plaster i wewnętrznie ma indeksator - ale nic nie wbudowane. Drugie podejście polegałoby na napisaniu metody, która powoduje, że plaster jest plastrem i oddaje wektor - zależy to od tego, czy chcesz mieć kopię czy nie.

using System; 
static class ArraySliceExt 
{ 
    public static ArraySlice2D<T> Slice<T>(this T[,] arr, int firstDimension) 
    { 
     return new ArraySlice2D<T>(arr, firstDimension); 
    } 
} 
class ArraySlice2D<T> 
{ 
    private readonly T[,] arr; 
    private readonly int firstDimension; 
    private readonly int length; 
    public int Length { get { return length; } } 
    public ArraySlice2D(T[,] arr, int firstDimension) 
    { 
     this.arr = arr; 
     this.firstDimension = firstDimension; 
     this.length = arr.GetUpperBound(1) + 1; 
    } 
    public T this[int index] 
    { 
     get { return arr[firstDimension, index]; } 
     set { arr[firstDimension, index] = value; } 
    } 
} 
public static class Program 
{ 
    static void Main() 
    { 
     double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } }; 
     var slice = d.Slice(0); 
     for (int i = 0; i < slice.Length; i++) 
     { 
      Console.WriteLine(slice[i]); 
     } 
    } 
} 
+0

dzięki za informację ... po tym, jak nie znalazłem nic wbudowanego, założyłem, że " Muszę napisać opakowanie, ale chciałem się upewnić, że nic mi nie umknęło. Dzięki jeszcze raz! – Kiril

+0

@Lirik zobacz aktualizację dla próbki –

+0

_ (Masz to, nie mówiąc o komentarzu z prawej strony) _ - Dobra robota, +1 –

3

Macierze prostokątne nie są przeznaczone do tego celu. Jeśli potrzebujesz tego typu funkcji, powinieneś przełączyć się na poszarpaną tablicę. Łatwo jest napisać funkcję, która przekształci prostokątny układ w postrzępiony.

Można również po prostu odbudować tę tablicę, wywołując GetLength (wymiar int) w odpowiednim wymiarze, a następnie odpowiednio ją zaindeksować, aby pobrać każdą wartość. Byłoby to tańsze niż konwersja całej tablicy, ale najtańszą opcją jest jej zmiana na tablice z poszarpanymi liniami.

+0

piszesz "Łatwo jest napisać funkcję, która przekształci prostokątny układ w postrzępiony." <--- ale może całkiem nieefektywna, jeśli duża tablica, ponieważ trzeba zeskanować całą tablicę? jak przekonwertować prostokątny na poszarpany bez odbudowywania go? – barlop

4

Ulepszona wersja that answer:

public static IEnumerable<T> SliceRow<T>(this T[,] array, int row) 
{ 
    for (var i = array.GetLowerBound(1); i <= array.GetUpperBound(1); i++) 
    { 
     yield return array[row, i]; 
    } 
} 

public static IEnumerable<T> SliceColumn<T>(this T[,] array, int column) 
{ 
    for (var i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++) 
    { 
     yield return array[i, column]; 
    } 
} 
+0

Dokładnie to, czego potrzebuję. IEnumerable. – realPT

Powiązane problemy