Подтвердить что ты не робот

Как получить размер (срез) из многомерного массива

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

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

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

4b9b3361

Ответ 1

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

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]);
        }
    }
}

Ответ 2

Улучшенная версия :

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];
    }
}

Ответ 3

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

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