2011-01-26 3 views
25

Я пытаюсь выяснить, как получить одно измерение из многомерного массива (ради аргумента, допустим, это 2D), у меня есть многомерный массив :Как получить измерение (срез) из многомерного массива

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

Если бы это был зазубренный массив, я бы просто позвонить d[0] и что даст мне массив {1, 2, 3, 4, 5}, есть способ, которым я могу достичь того же с 2D массив?

+1

Это звучит, как вы хотите, чтобы создать массив, который ссылается на срез массива. Я не думаю, что это возможно. – Gabe

+0

@Gabe, yah, я просмотрел документацию, и я не мог видеть ничего, что могло бы помочь мне получить кусочек, поэтому я решил подтвердить это сообщество. Спасибо за информацию! :) – Kiril

+2

Я только заметил, что мой вопрос повторяется: http://stackoverflow.com/questions/1406083/array-slice-in-c – Kiril

ответ

17

Нет. Вы могли бы, конечно, написать класс-оболочку, представляющий срез, и внутренний указатель, но ничего не встроенный. Другим подходом было бы написать метод, который делает копию фрагмента и передает обратно вектор - это зависит от того, хотите ли вы получить копию или нет.

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

спасибо за информацию ... после того, как я не нашел ничего встроенного Я предполагал, d должен написать обертку, но я хотел убедиться, что ничего не пропустил. Еще раз спасибо! – Kiril

+0

@Lirik см. Обновление для образца –

+0

_ (У вас есть это, не говоря уже о правых комментариях) _ - Хорошая работа, +1 –

3

Прямоугольные массивы для этой цели не построены. Если вам нужен такой тип функциональности, вы должны переключиться на массив с зазубринами. Очень просто написать функцию, которая преобразует прямоугольный массив в неровную.

Вы также можете просто перестроить этот массив, вызвав GetLength (int dimension) в соответствующем измерении и затем проиндексируя его правильно, чтобы получить каждое значение. Это было бы дешевле, чем преобразование всего массива, но самый дешевый вариант - изменить его на использование зубчатых массивов.

+0

вы пишете: «Очень просто написать функцию, которая преобразует прямоугольный массив в зубчатый». <--- но, возможно, довольно неэффективно, если большой массив, потому что вам нужно отсканировать весь массив? как вы преобразовываете прямоугольник в зубчатый, не перестраивая его? – barlop

4

Улучшенная версия 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

То, что мне нужно. IEnumerable. – realPT

Смежные вопросы