我认为应该这样做
public static class ArrayExtensions
{
public static T[] GetSubArray<T>( this T[] origin, int originDimensionsX, int originDimensionsY, int startPositionX, int startPositionY, int targetDimensionsX, int targetDimensionsY)
{
// First of all some checks
if(origin == null) return null;
if(origin.Length == 0) return new T[0];
if(originDimensionsX < 0 || originDimensionsY < 0 || originDimensionsX * originDimensionsY != origin.Length) throw new ArgumentOutOfRangeException($"Given dimensions {originDimensionsX},{originDimensionsY} do not match the given array length {origin.Length}!");
if(startPositionX < 0 || startPositionX > originDimensionsX - 1) throw new ArgumentOutOfRangeException($"Given startPosition {startPositionX} is outside of the origin dimensions {originDimensionsX}!");
if(startPositionY < 0 || startPositionY > originDimensionsY - 1) throw new ArgumentOutOfRangeException($"Given startPosition {startPositionY} is outside of the origin dimensions {originDimensionsY}!");
if(targetDimensionsX < 0 || targetDimensionsY < 0) throw new ArgumentOutOfRangeException ("TargetDimensions may not be negative!");
if(startPositionX + targetDimensionsX > originDimensionsX || startPositionY + targetDimensionsY > originDimensionsY) throw new ArgumentOutOfRangeException ($"Given TargetDimensions {targetDimensionsX},{targetDimensionsY} starting at {startPositionX},{startPositionY} does not fit into originDimensions {originDimensionsX},{originDimensionsY}!");
var output = new T[targetDimensionsX * targetDimensionsY];
var subIndex = 0;
for(var y = startPositionY; y < startPositionY + targetDimensionsY; y++)
{
for(var x = startPositionX; x < startPositionX + targetDimensionsX; x++)
{
output[subIndex++] = origin[x + y * originDimensionsX];
}
}
return output;
}
}
例子
var origin = new []
{
0, 1, 2,
3, 4, 5,
6, 7, 8
};
var subArray = origin.GetSubArray(3, 3, 1, 1, 2, 2);
Debug.Log(string.Join(",", subArray));
会
4, 5, 7, 8
由于对于 X 维度,我们总是为大型数组复制 连续 值,它可能比使用内部 for 循环更有效
Array.Copy
public static T[] GetSubArray(this int[] origin, int originDimensionsX, int originDimensionsY, int startPositionX, int startPositionY, int targetDimensionsX, int targetDimensionsY)
{
// First of all some checks
if(origin == null) return null;
if(origin.Length == 0) return new T[0];
if(originDimensionsX < 0 || originDimensionsY < 0 || originDimensionsX * originDimensionsY != origin.Length) throw new ArgumentOutOfRangeException($"Given dimensions {originDimensionsX},{originDimensionsY} do not match the given array length {origin.Length}!");
if(startPositionX < 0 || startPositionX > originDimensionsX - 1) throw new ArgumentOutOfRangeException($"Given startPosition {startPositionX} is outside of the origin dimensions {originDimensionsX}!");
if(startPositionY < 0 || startPositionY > originDimensionsY - 1) throw new ArgumentOutOfRangeException($"Given startPosition {startPositionY} is outside of the origin dimensions {originDimensionsY}!");
if(targetDimensionsX < 0 || targetDimensionsY < 0) throw new ArgumentOutOfRangeException ("TargetDimensions may not be negative!");
if(startPositionX + targetDimensionsX > originDimensionsX || startPositionY + targetDimensionsY > originDimensionsY) throw new ArgumentOutOfRangeException ($"Given TargetDimensions {targetDimensionsX},{targetDimensionsY} starting at {startPositionX},{startPositionY} does not fit into originDimensions {originDimensionsX},{originDimensionsY}!");
var output = new T[targetDimensionsX * targetDimensionsY];
var subIndex = 0;
for(var y = startPositionY; y < startPositionY + targetDimensionsY; y++)
{
Array.Copy(origin, startPositionX + y * originDimensionsX, output, subIndex, targetDimensionsX);
subIndex += targetDimensionsX;
}
return output;
}
}
或者你也可以下到字节级别,直接使用 Buffer.BlockCopy (假设现在是 int 或其他 const 大小的基本类型数组 - 不是通用的,你需要知道常量字节大小你的类型!)
const int SIZEOF_INT = sizeof(int);
public static int[] GetSubArray(this int[] origin, int originDimensionsX, int originDimensionsY, int startPositionX, int startPositionY, int targetDimensionsX, int targetDimensionsY)
{
// First of all some checks
if(origin == null) return null;
if(origin.Length == 0) return new T[0];
if(originDimensionsX < 0 || originDimensionsY < 0 || originDimensionsX * originDimensionsY != origin.Length) throw new ArgumentOutOfRangeException($"Given dimensions {originDimensionsX},{originDimensionsY} do not match the given array length {origin.Length}!");
if(startPositionX < 0 || startPositionX > originDimensionsX - 1) throw new ArgumentOutOfRangeException($"Given startPosition {startPositionX} is outside of the origin dimensions {originDimensionsX}!");
if(startPositionY < 0 || startPositionY > originDimensionsY - 1) throw new ArgumentOutOfRangeException($"Given startPosition {startPositionY} is outside of the origin dimensions {originDimensionsY}!");
if(targetDimensionsX < 0 || targetDimensionsY < 0) throw new ArgumentOutOfRangeException ("TargetDimensions may not be negative!");
if(startPositionX + targetDimensionsX > originDimensionsX || startPositionY + targetDimensionsY > originDimensionsY) throw new ArgumentOutOfRangeException ($"Given TargetDimensions {targetDimensionsX},{targetDimensionsY} starting at {startPositionX},{startPositionY} does not fit into originDimensions {originDimensionsX},{originDimensionsY}!");
var output = new int[targetDimensionsX * targetDimensionsY];
var subIndex = 0;
for(var y = startPositionY; y < startPositionY + targetDimensionsY; y++)
{
// In this case the indices are all referring to bytes instead of array index
Buffer.BlockCopy(origin, (startPositionX + y * originDimensionsX) * SIZEOF_INT, output, subIndex * SIZEOF_INT, targetDimensionsX * SIZEOF_INT);
subIndex += targetDimensionsX;
}
return output;
}
}
注意:在智能手机上输入 -> 未经测试,但我希望思路清晰