【问题标题】:Flatten a volume of a 3D array into a 1D array of objects将 3D 阵列的体积展平为 1D 对象阵列
【发布时间】:2012-01-16 22:20:46
【问题描述】:

给我一​​个类型的 3D 地图,其长度和宽度是统一的,但深度是锯齿状的:

public class Map<T>
{
    T[,][] map;
    ...
}

返回一个一维数组的最佳方法是返回存在于由二维区域定义的体积内的所有类型对象以及该区域内的所有深度。例如,我可能有一个数组符号覆盖,如下所示:

public IEnumerable<T> this[Rectangle area]
{
    get {...}
}

或者只是

public IEnumerable<T> this[int x, int y, int width, int length]
{
    get {...}
}

我真诚地希望有一个快速的 LINQ 解决方案,但性能优于该解决方案的视觉优雅。返回的展平数组中对象的顺序并不重要。如果有人对此有任何建议或经验,请分享您的智慧。

或者,如果我可以使用另一个数据结构来执行我不知道的相同功能,我会很乐意使用它。

如果我的问题不清楚,请询问更多详情。

【问题讨论】:

    标签: c# .net arrays data-structures multidimensional-array


    【解决方案1】:

    你在寻找这样的东西吗?

    public IEnumerable<T> this[int left, int top, int width, int height]
    {
        get
        {
            return from x in Enumerable.Range(left, width)
                   from y in Enumerable.Range(top, height)
                   from i in this.map[x, y]
                   select i;
        }
    }
    

    【讨论】:

    • 此解决方案效果很好,但比 for 循环解决方案稍慢。只是轻微。当迭代 4700x4700 区域时,此解决方案的时钟为 3.4 秒,而 for 循环解决方案为 1.7 秒。
    【解决方案2】:

    这可能也有效(没有 Linq)

        public IEnumerable<T> this[int x, int y, int width, int length]
        {
            get
            {
                for (int i = 0; i < length; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        for (int k = 0; k < map[x + i, y + j].Length; k++)
                        {
                            yield return map[x + i, y + j][k];
                        }
                    }
                }
            }
        }
    

    【讨论】:

    • 这个解决方案和 LINQ 解决方案都工作得很好,这个解决方案比 LINQ 有轻微的性能提升,这就是我给你答案的原因。
    猜你喜欢
    • 2014-03-03
    • 2013-12-14
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 2019-06-28
    相关资源
    最近更新 更多