例如,如果我想对该数组中的元素进行迭代test
和perfrorm操作,但必须以特定方式对其进行格式化。
基本上我试图使用2d数组遍历2d数组。
double[,] test = {
{9, 8, 7, 6, 5, 4, 3, 2},
{8, 7, 6, 5, 4, 3, 2, 1},
{7, 6, 5, 4, 3, 2, 1, 0},
{6, 5, 4, 3, 2, 1, 0, 0},
{5, 4, 3, 2, 1, 0, 0, 0},
{4, 3, 2, 1, 0, 0, 0, 0},
{3, 2, 1, 0, 0, 0, 0, 0},
{2, 1, 0, 0, 0, 0, 0, 0},
};
double[,] subset = new double[2,2]; //used in math
我希望能够做的是迭代任何大小的矩阵(假设它们的大小和方形均匀),每次迭代看起来像这样:
Iteration 1:
subset[0,0] = test[0,0];
subset[0,1] = test[0,1];
subset[1,0] = test[1,0];
subset[1,1] = test[1,1];
所以基本上它从大矩阵中选择了与子集相同的正方形。
Iteration 2:
subset[0,2] = test[0,2];
subset[1,2] = test[1,2];
subset[0,3] = test[0,3];
subset[1,3] = test[1,3];
答案 0 :(得分:1)
您可以通过扩展方法执行此操作。一些值得一提的事情:
Array.Copy
而不是手动分配元素应该会产生更好的性能。yield return
来创建IEnumerable
。然后,您可以使用foreach
循环对其进行迭代,或执行其他操作。<强>实施强>
static class MatrixExtensions
{
public static IEnumerable<T[,]> ChunkMatrix<T>(this T[,] inputMatrix, int chunkWidth, int chunkHeight)
{
int inputWidth = inputMatrix.GetLength(0);
int inputHeight = inputMatrix.GetLength(1);
for(int i = 0; i < inputWidth; i += chunkWidth)
{
for(int j = 0; j < inputHeight; j += chunkHeight)
{
T[,] chunk = new T[chunkWidth, chunkHeight];
for(int k = 0; k < chunkWidth; k++)
{
int sourceIndex = i*inputWidth + k* inputWidth + j;
var destinationIndex = k* chunkHeight;
Array.Copy(inputMatrix, sourceIndex, chunk, destinationIndex, chunkHeight);
}
yield return chunk;
}
}
}
}
<强>用法:强>
double[,] test = {
{1, 2, 3, 4, 5, 6, 7, 8},
{9, 10, 11, 12, 13, 14, 15, 16},
{17, 18, 19, 20, 21, 22, 23, 24},
{25, 26, 27, 28, 29, 30, 31, 32},
{33, 34, 35, 36, 37, 38, 39, 40},
{41, 42, 43, 44, 45, 46, 47, 48},
{49, 50, 51, 52, 53, 54, 55, 56},
{57, 58, 59, 60, 61, 62, 63, 64},
};
foreach(double[,] chunk in test.ChunkMatrix(2, 2))
{
// First iteration:
// 1 2
// 9 10
//
// Second iteration:
// 3 4
// 11 12
//
// ...
}
我将测试数据更改为不包含重复值,以便更好地说明效果。
应该注意的是,我的实现将无法在尺寸不是块的倍数的矩阵上正常工作。尺寸,正如评论中提到的那样,情况永远不会如此。如果需要,修改它以考虑这种情况不应该太难。
答案 1 :(得分:0)
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
const int COLUMNS = 8;
const int ROWS = 8;
const int SIZE = 2;
static void Main(string[] args)
{
double[,] test = {
{9, 8, 7, 6, 5, 4, 3, 2},
{8, 7, 6, 5, 4, 3, 2, 1},
{7, 6, 5, 4, 3, 2, 1, 0},
{6, 5, 4, 3, 2, 1, 0, 0},
{5, 4, 3, 2, 1, 0, 0, 0},
{4, 3, 2, 1, 0, 0, 0, 0},
{3, 2, 1, 0, 0, 0, 0, 0},
{2, 1, 0, 0, 0, 0, 0, 0},
};
for (int i = 0; i < COLUMNS; i += SIZE)
{
for (int j = 0; j < ROWS; j += SIZE)
{
for (int k = j; k < j + SIZE; k++)
{
for (int l = i; l < i + SIZE; l++)
{
Console.WriteLine("test[{0}, {1}] = {2}", k, l, test[k, l]);
}
}
}
}
Console.ReadLine();
}
}
}
答案 2 :(得分:0)
我并不是说这是最好的解决方案,但是当我查看yield
语句时,我设法让它使用此方法。
public static double[,] GetMapSection(Rectangle area, double[,] map) {
double[,] result = new double[area.Width, area.Height];
for (Int32 y = 0; y < area.Height; ++y) {
for (Int32 x = 0; x < area.Width; ++x) {
result[x, y] = map[x + area.X, y + area.Y];
}
}
return result;
}
我通过以下方式致电:
List<double[,]> testChannel = new List<double[,]>();
for (int i = 0; i < Math.Sqrt(large_mapdata.Length); i+=8) {
for (int j = 0; j < Math.Sqrt(large_mapdata.Length); j+=8) {
testChannel.Add(GetMapSection(new Rectangle(i, j, 8, 8), large_mapdata));
}
}
在这个例子中,我从一个32x32大小的数组中创建8x8块。 我可以确认这对我有用,并且比以前更清洁。