В зависимости от использования меньшего массива это может удовлетворить ваши потребности.
Представлять подразделы (кусок) массив, вместо того чтобы создавать новый массив или делать какое-либо копирование, вы можете написать свой собственный класс, который служит видом на этот кусок массива.
Обратите внимание, что в этом примере имеет следующие свойства:
- Нет защитных положений в конструктор
- Кусок всегда куба (х, у, длина г равны)
- длина Кусок всегда нечетно (поскольку мы расширяем из точки отсчета)
public class ArrayChunk<T>
{
// Array this chunk is from.
private readonly T[,,] _parentArray;
// Point of reference.
private readonly int _x, _y, _z;
// How many elements to move outwards in each direction from point of reference.
private readonly int _numToExpand;
public ArrayChunk(T[,,] parentArray, int x, int y, int z, int numToExpand)
{
_parentArray = parentArray;
_x = x;
_y = y;
_z = z;
_numToExpand = numToExpand;
}
public int Length => _numToExpand*2 + 1;
public T this[int x, int y, int z]
{
get
{
// Make sure index is within chunk range.
EnsureInChunkRange(x, y, z);
// Map chunk index to parent array index.
int parentX = MapToParent(_x, x),
parentY = MapToParent(_y, y),
parentZ = MapToParent(_z, z);
// If parent array index is in parent array range, return element from parent array.
if (IsInRangeOfParent(parentX, parentY, parentZ))
return _parentArray[parentX, parentY, parentZ];
// Otherwise return default element for type T.
return default(T);
}
set
{
EnsureInChunkRange(x, y, z);
int parentX = MapToParent(_x, x),
parentY = MapToParent(_y, y),
parentZ = MapToParent(_z, z);
if (IsInRangeOfParent(parentX, parentY, parentZ))
_parentArray[parentX, parentY, parentZ] = value;
else
throw new InvalidOperationException();
}
}
private void EnsureInChunkRange(int x, int y, int z)
{
if (x < 0 || y < 0 || z < 0 ||
x >= Length || y >= Length || z >= Length)
{
throw new IndexOutOfRangeException();
}
}
private int MapToParent(int referenceIndex, int index)
{
return referenceIndex - _numToExpand + index;
}
private bool IsInRangeOfParent(int parentX, int parentY, int parentZ)
{
return
parentX >= 0 &&
parentY >= 0 &&
parentZ >= 0 &&
parentX < _parentArray.GetLength(0) &&
parentY < _parentArray.GetLength(1) &&
parentZ < _parentArray.GetLength(2);
}
}
Чтобы легко получить кусок от массива, можно объявить метод расширения:
public static class ArrayChunkExtensions
{
public static ArrayChunk<T> GetChunk<T>(this T[,,] array, int x, int y, int z, int numToExpand)
{
return new ArrayChunk<T>(array, x, y, z, numToExpand);
}
}
Вот Пример использования:
Action<int, Action<int, int, int>> iterate = (length, action) =>
{
for (int x = 0; x < length; x++)
for (int y = 0; y < length; y++)
for (int z = 0; z < length; z++)
action(x, y, z);
};
// Create 5x5x5 parent array.
const int size = 5;
var array = new string[size, size, size];
iterate(size, (x, y, z) => array[x, y, z] = $"x:{x} y:{y} z:{z}");
// Take 3x3x3 chunk from parent array center.
const int indexOfReference = 2;
const int numToExpand = 1;
ArrayChunk<string> chunk = array.GetChunk(indexOfReference, indexOfReference, indexOfReference, numToExpand);
iterate(chunk.Length, (x, y, z) => Console.WriteLine(chunk[x, y, z]));
Спасибо, выглядит прикосновение более эффективной, чем то, что я придумал , Я попробую и дам вам знать/отметьте как ответ –
Дайте мне знать, если у вас возникнут проблемы или возникнут вопросы. –