如何从多维数组中获取一个维度(切片)

39

我正在尝试找出如何从一个多维数组(为了说明问题,假设它是2D)中获取单个维度,我有一个多维数组:

double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } };
如果它是一个锯齿状数组,我只需调用 d[0],就会给我一个包含 {1, 2, 3, 4, 5} 数组的数组,那么是否有一种方法可以在二维数组中实现相同的效果?

1
听起来你想创建一个引用数组的切片。我认为这是不可能的。 - Gabe
@Gabe,是的,我查看了文档,没有找到任何有助于获取切片的东西,所以我决定向社区确认。谢谢信息! :) - Kiril
2
我刚刚注意到我的问题是一个重复的问题:https://dev59.com/SXM_5IYBdhLWcg3wXx_Z - Kiril
4个回答

25

不可以。当然,你可以写一个代表切片并且内部有索引器的包装类,但是没有内置的方法。另一种方法是编写一个制作切片副本并返回向量的方法——这取决于你是否需要副本

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

感谢提供信息...在未发现任何内置功能后,我假设我必须编写一个包装器,但我想确定我没有漏掉任何东西。再次感谢! - Kiril
(你明白了,不用管右侧的注释)-- 做得好,+1 - Brad Christie

15

这是该回答的改进版本:

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

1
正是我所需要的。IEnumerable。 - realPT

3

矩形数组并不适用于此目的。如果您需要该类型的功能,应切换到锯齿数组。编写一个将矩形数组转换为锯齿数组的函数非常简单。

您还可以通过在适当的维度上调用GetLength(int dimension)来重建该数组,然后正确地索引它以检索每个值。这比转换整个数组要便宜,但最便宜的选项是将其更改为使用锯齿数组。


2
你写的“编写一个将矩形数组转换为锯齿形数组的函数非常简单。”<---但如果是大型数组可能相当低效,因为必须扫描整个数组?如何在不重建数组的情况下将矩形数组转换为锯齿形数组? - barlop

2

这应该复制一个锯齿数组的a[r]功能:

T[] Slice<T>(T[,] a, int r) => Enumerable.Range(0, a.GetUpperBound(1) + 1).Select(i => a[r, i]).ToArray();

不要使用GetUpperBound(1) + 1,直接使用GetLength(1)会更清晰明了。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接