Как получить измерение (срез) из многомерного массива
Я пытаюсь выяснить, как получить одно измерение из многомерного массива (для аргумента, скажем, это 2D), у меня есть многомерный массив:
double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } };
Если бы это был зубчатый массив, я бы просто позвонил d[0]
и это дало бы мне массив {1, 2, 3, 4, 5}
, есть ли способ добиться того же с 2D-массивом?
3 ответов
нет. Конечно, вы можете написать класс - оболочку, который представляет срез и имеет индексатор внутри, но ничего встроенного. Другим подходом было бы написать метод, который делает скопировать среза и руки назад вектор - это зависит от того, хотите ли вы скопировать или нет.
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]);
}
}
}
улучшенная версия что ответ:
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];
}
}
прямоугольные массивы не построены для этой цели. Если вам нужен этот тип функциональности, вы должны переключиться на массив массивов. Довольно просто написать функцию, которая преобразует прямоугольный массив в зубчатый.
вы также можете просто перестроить этот массив, вызвав GetLength (int dimension) в соответствующем измерении, а затем индексировать его должным образом, чтобы получить каждое значение. Это было бы дешевле, чем конвертировать весь массив, но самый дешевый вариант - измените его на использование зубчатых массивов.