在3D列表中查找所有相邻的项目

本文关键字:项目 3D 列表 查找 | 更新日期: 2023-09-27 17:53:40

我有一个3D列表(3个嵌套列表),对于列表中的每个项目,我需要找到相邻的项目。目前,我正在为每个相邻的项目创建一个数组,并将其存储在每个项目中。这是相当资源密集的,所以我希望能简化一点。

我正在考虑使用这种方法:

for (int i = 0; i < 8; i++)
{
    switch (i)
    {
        case (0):
            mapCell neighbor = myMap.Depth[z].Rows[x].Columns[y - 1];
        case (1):
            mapCell neighbor = myMap.Depth[z].Rows[x].Columns[y + 1];
        case (2):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y];
        case (3):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y];
        case (4):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y + 1];
        case (5):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y - 1];
        case (6):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y + 1];
        case (7):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y - 1];
    }
    // do some stuff with the neighbor here
}

就性能而言,这比我现在拥有的要好得多,但我想知道是否有更简单的方法来实现这一点?这看起来有点乱,我真的觉得有一种方法可以在一行内完成,但我就是想不出数学方法。

edit:对不起,我可能遗漏了一些重要的细节。与"邻居"变量一起工作的代码被忽略了,因为它很长,对解决方案没有帮助。我不需要维护"邻居"变量的列表(这就是我目前所做的,它使用了太多的内存(大约400兆)。我只需要一种快速的方法来查看每个项目,找到相邻的8个项目中的每一个,一次处理一个,然后移动到下一个节点。上面的代码可以遍历它们,但感觉不是最优化的方法。

在3D列表中查找所有相邻的项目

看起来你实际上是在3D数据结构中以给定深度在2D数组中找到邻居。也就是说,你忽略了相邻深度的邻居。

你的方法可能非常高效。你可以找到一些更花哨的方式,涉及更少的输入,例如,以下是关于SO的类似问题的答案,但我怀疑它是否会更快。

显然,你还需要在你的代码中包含一些检查,以处理不会有8个邻居的边缘项。

private void DoSomethingWithNeighbours(int x, int y, int z)
{
    foreach (var neighbout in this.GetNeighbours(x, y, z)
    {
        // ...
    }
}
private IEnumerable<Item> GetNeighbours(int x, int y, int z)
{
    if (x > 0)
    {
        if (y > 0)
        {
            yield return myMap.Depth[z].Rows[x - 1].Columns[y - 1];
        }
        yield return myMap.Depth[z].Rows[x - 1].Columns[y];
        if (y < ColumnCount - 1)
        {
            yield return myMap.Depth[z].Rows[x - 1].Columns[y + 1];
        }
    }
    if (y > 0)
    {
        yield return myMap.Depth[z].Rows[x].Columns[y - 1];
    }
    if (y < ColumnCount - 1)
    {
        yield return myMap.Depth[z].Rows[x].Columns[y + 1];
    }
    if (x < RowCount - 1)
    {
        if (y > 0)
        {
            yield return myMap.Depth[z].Rows[x + 1].Columns[y - 1];
        }
        yield return myMap.Depth[z].Rows[x + 1].Columns[y];
        if (y < ColumnCount - 1)
        {
            yield return myMap.Depth[z].Rows[x + 1].Columns[y + 1];
        }
    }
}

或以下更简洁的替代方案,只有边际性能成本:

private IEnumerable<int> GetNeighbours2(int x, int y, int z)
{
    for (int i = x - 1; i <= x + 1; ++i)
    {
        for (int j = y - 1; j <= y + 1; ++j)
        {
            if (i >= 0 && i < Rows && j >= 0 && j < Cols && !(i == x && j == y))
            {
                yield return myMap.Depth[z].Rows[i].Columns[j];
            }
        }
    }
}